import { isPlatformServer } from '@angular/common';
import { NgxsBootstrapper } from '@ngxs/store/internals';
import { Observable, Subject, BehaviorSubject, of, forkJoin, empty, throwError, from } from 'rxjs';
import { map, filter, shareReplay, exhaustMap, take, catchError, defaultIfEmpty, mergeMap, takeUntil, tap, distinctUntilChanged } from 'rxjs/operators';
import { __spread, __extends, __values, __assign } from 'tslib';
import { NgZone, PLATFORM_ID, Injectable, Inject, InjectionToken, Optional, SkipSelf, ErrorHandler, getPlatform, COMPILER_OPTIONS, isDevMode, Injector, NgModule, APP_BOOTSTRAP_LISTENER } from '@angular/core';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var DispatchOutsideZoneNgxsExecutionStrategy = /** @class */ (function () {
    function DispatchOutsideZoneNgxsExecutionStrategy(_ngZone, _platformId) {
        this._ngZone = _ngZone;
        this._platformId = _platformId;
        this.verifyZoneIsNotNooped(this._ngZone);
    }
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    DispatchOutsideZoneNgxsExecutionStrategy.prototype.enter = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        if (isPlatformServer(this._platformId)) {
            return this.runInsideAngular(func);
        }
        return this.runOutsideAngular(func);
    };
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    DispatchOutsideZoneNgxsExecutionStrategy.prototype.leave = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        return this.runInsideAngular(func);
    };
    /**
     * @private
     * @template T
     * @param {?} func
     * @return {?}
     */
    DispatchOutsideZoneNgxsExecutionStrategy.prototype.runInsideAngular = /**
     * @private
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        if (NgZone.isInAngularZone()) {
            return func();
        }
        return this._ngZone.run(func);
    };
    /**
     * @private
     * @template T
     * @param {?} func
     * @return {?}
     */
    DispatchOutsideZoneNgxsExecutionStrategy.prototype.runOutsideAngular = /**
     * @private
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        if (NgZone.isInAngularZone()) {
            return this._ngZone.runOutsideAngular(func);
        }
        return func();
    };
    /**
     * @private
     * @param {?} ngZone
     * @return {?}
     */
    DispatchOutsideZoneNgxsExecutionStrategy.prototype.verifyZoneIsNotNooped = /**
     * @private
     * @param {?} ngZone
     * @return {?}
     */
    function (ngZone) {
        /* - Removed because unsafe for Angular 5 - investigate
        if (ngZone instanceof NoopNgZone) {
          console.warn(
            'Your application was bootstrapped with nooped zone and your execution strategy requires an ngZone'
          );
        }
        */
    };
    DispatchOutsideZoneNgxsExecutionStrategy.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    DispatchOutsideZoneNgxsExecutionStrategy.ctorParameters = function () { return [
        { type: NgZone },
        { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
    ]; };
    return DispatchOutsideZoneNgxsExecutionStrategy;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
var ROOT_STATE_TOKEN = new InjectionToken('ROOT_STATE_TOKEN');
/** @type {?} */
var FEATURE_STATE_TOKEN = new InjectionToken('FEATURE_STATE_TOKEN');
/** @type {?} */
var META_KEY = 'NGXS_META';
/** @type {?} */
var META_OPTIONS_KEY = 'NGXS_OPTIONS_META';
/** @type {?} */
var SELECTOR_META_KEY = 'NGXS_SELECTOR_META';
/** @type {?} */
var NGXS_PLUGINS = new InjectionToken('NGXS_PLUGINS');
/**
 * The NGXS config settings.
 */
var NgxsConfig = /** @class */ (function () {
    function NgxsConfig() {
        /**
         * Defining the default state before module initialization
         * This is convenient if we need to create a define our own set of states.
         * (default: {})
         */
        this.defaultsState = {};
        this.compatibility = {
            strictContentSecurityPolicy: false
        };
        this.executionStrategy = DispatchOutsideZoneNgxsExecutionStrategy;
    }
    NgxsConfig.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    NgxsConfig.ctorParameters = function () { return []; };
    return NgxsConfig;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/*
 * Internal execution strategy injection token
 */
/** @type {?} */
var NGXS_EXECUTION_STRATEGY = new InjectionToken('NGXS_EXECUTION_STRATEGY');

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Ensures metadata is attached to the class and returns it.
 *
 * @ignore
 * @param {?} target
 * @return {?}
 */
function ensureStoreMetadata(target) {
    if (!target.hasOwnProperty(META_KEY)) {
        /** @type {?} */
        var defaultMetadata = {
            name: null,
            actions: {},
            defaults: {},
            path: null,
            selectFromAppState: null,
            children: [],
            instance: null
        };
        Object.defineProperty(target, META_KEY, { value: defaultMetadata });
    }
    return getStoreMetadata(target);
}
/**
 * Get the metadata attached to the state class if it exists.
 *
 * @ignore
 * @param {?} target
 * @return {?}
 */
function getStoreMetadata(target) {
    return (/** @type {?} */ (target[META_KEY]));
}
/**
 * Ensures metadata is attached to the selector and returns it.
 *
 * @ignore
 * @param {?} target
 * @return {?}
 */
function ensureSelectorMetadata(target) {
    if (!target.hasOwnProperty(SELECTOR_META_KEY)) {
        /** @type {?} */
        var defaultMetadata = {
            selectFromAppState: null,
            originalFn: null,
            containerClass: null,
            selectorName: null
        };
        Object.defineProperty(target, SELECTOR_META_KEY, { value: defaultMetadata });
    }
    return getSelectorMetadata(target);
}
/**
 * Get the metadata attached to the selector if it exists.
 *
 * @ignore
 * @param {?} target
 * @return {?}
 */
function getSelectorMetadata(target) {
    return target[SELECTOR_META_KEY];
}
/**
 * Get a deeply nested value. Example:
 *
 *    getValue({ foo: bar: [] }, 'foo.bar') //=> []
 *
 * Note: This is not as fast as the `fastPropGetter` but is strict Content Security Policy compliant.
 * See perf hit: https://jsperf.com/fast-value-getter-given-path/1
 *
 * @ignore
 * @param {?} paths
 * @return {?}
 */
function compliantPropGetter(paths) {
    /** @type {?} */
    var copyOfPaths = __spread(paths);
    return (/**
     * @param {?} obj
     * @return {?}
     */
    function (obj) { return copyOfPaths.reduce((/**
     * @param {?} acc
     * @param {?} part
     * @return {?}
     */
    function (acc, part) { return acc && acc[part]; }), obj); });
}
/**
 * The generated function is faster than:
 * - pluck (Observable operator)
 * - memoize
 *
 * @ignore
 * @param {?} paths
 * @return {?}
 */
function fastPropGetter(paths) {
    /** @type {?} */
    var segments = paths;
    /** @type {?} */
    var seg = 'store.' + segments[0];
    /** @type {?} */
    var i = 0;
    /** @type {?} */
    var l = segments.length;
    /** @type {?} */
    var expr = seg;
    while (++i < l) {
        expr = expr + ' && ' + (seg = seg + '.' + segments[i]);
    }
    /** @type {?} */
    var fn = new Function('store', 'return ' + expr + ';');
    return (/** @type {?} */ (fn));
}
/**
 * Get a deeply nested value. Example:
 *
 *    getValue({ foo: bar: [] }, 'foo.bar') //=> []
 *
 * @ignore
 * @param {?} paths
 * @param {?} config
 * @return {?}
 */
function propGetter(paths, config) {
    if (config && config.compatibility && config.compatibility.strictContentSecurityPolicy) {
        return compliantPropGetter(paths);
    }
    else {
        return fastPropGetter(paths);
    }
}
/**
 * Given an array of states, it will return a object graph. Example:
 *    const states = [
 *      Cart,
 *      CartSaved,
 *      CartSavedItems
 *    ]
 *
 * would return:
 *
 *  const graph = {
 *    cart: ['saved'],
 *    saved: ['items'],
 *    items: []
 *  };
 *
 * @ignore
 * @param {?} stateClasses
 * @return {?}
 */
function buildGraph(stateClasses) {
    /** @type {?} */
    var findName = (/**
     * @param {?} stateClass
     * @return {?}
     */
    function (stateClass) {
        /** @type {?} */
        var meta = stateClasses.find((/**
         * @param {?} g
         * @return {?}
         */
        function (g) { return g === stateClass; }));
        if (!meta) {
            throw new Error("Child state not found: " + stateClass + ". \r\nYou may have forgotten to add states to module");
        }
        return (/** @type {?} */ ((/** @type {?} */ (meta[META_KEY])).name));
    });
    return stateClasses.reduce((/**
     * @param {?} result
     * @param {?} stateClass
     * @return {?}
     */
    function (result, stateClass) {
        var _a = (/** @type {?} */ (stateClass[META_KEY])), name = _a.name, children = _a.children;
        result[(/** @type {?} */ (name))] = (children || []).map(findName);
        return result;
    }), {});
}
/**
 * Given a states array, returns object graph
 * returning the name and state metadata. Example:
 *
 *  const graph = {
 *    cart: { metadata }
 *  };
 *
 * @ignore
 * @param {?} states
 * @return {?}
 */
function nameToState(states) {
    return states.reduce((/**
     * @param {?} result
     * @param {?} stateClass
     * @return {?}
     */
    function (result, stateClass) {
        /** @type {?} */
        var meta = (/** @type {?} */ (stateClass[META_KEY]));
        result[(/** @type {?} */ (meta.name))] = stateClass;
        return result;
    }), {});
}
/**
 * Given a object relationship graph will return the full path
 * for the child items. Example:
 *
 *  const graph = {
 *    cart: ['saved'],
 *    saved: ['items'],
 *    items: []
 *  };
 *
 * would return:
 *
 *  const r = {
 *    cart: 'cart',
 *    saved: 'cart.saved',
 *    items: 'cart.saved.items'
 *  };
 *
 * @ignore
 * @param {?} obj
 * @param {?=} newObj
 * @return {?}
 */
function findFullParentPath(obj, newObj) {
    if (newObj === void 0) { newObj = {}; }
    /** @type {?} */
    var visit = (/**
     * @param {?} child
     * @param {?} keyToFind
     * @return {?}
     */
    function (child, keyToFind) {
        for (var key in child) {
            if (child.hasOwnProperty(key) && child[key].indexOf(keyToFind) >= 0) {
                /** @type {?} */
                var parent_1 = visit(child, key);
                return parent_1 !== null ? parent_1 + "." + key : key;
            }
        }
        return null;
    });
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            /** @type {?} */
            var parent_2 = visit(obj, key);
            newObj[key] = parent_2 ? parent_2 + "." + key : key;
        }
    }
    return newObj;
}
/**
 * Given a object graph, it will return the items topologically sorted Example:
 *
 *  const graph = {
 *    cart: ['saved'],
 *    saved: ['items'],
 *    items: []
 *  };
 *
 * would return:
 *
 *  const results = [
 *    'items',
 *    'saved',
 *    'cart'
 *  ];
 *
 * @ignore
 * @param {?} graph
 * @return {?}
 */
function topologicalSort(graph) {
    /** @type {?} */
    var sorted = [];
    /** @type {?} */
    var visited = {};
    /** @type {?} */
    var visit = (/**
     * @param {?} name
     * @param {?=} ancestors
     * @return {?}
     */
    function (name, ancestors) {
        if (ancestors === void 0) { ancestors = []; }
        if (!Array.isArray(ancestors)) {
            ancestors = [];
        }
        ancestors.push(name);
        visited[name] = true;
        graph[name].forEach((/**
         * @param {?} dep
         * @return {?}
         */
        function (dep) {
            if (ancestors.indexOf(dep) >= 0) {
                throw new Error("Circular dependency '" + dep + "' is required by '" + name + "': " + ancestors.join(' -> '));
            }
            if (visited[dep]) {
                return;
            }
            visit(dep, ancestors.slice(0));
        }));
        if (sorted.indexOf(name) < 0) {
            sorted.push(name);
        }
    });
    Object.keys(graph).forEach((/**
     * @param {?} k
     * @return {?}
     */
    function (k) { return visit(k); }));
    return sorted.reverse();
}
/**
 * Returns if the parameter is a object or not.
 *
 * @ignore
 * @param {?} obj
 * @return {?}
 */
function isObject(obj) {
    return (typeof obj === 'object' && obj !== null) || typeof obj === 'function';
}
/** @type {?} */
var DOLLAR_CHAR_CODE = 36;
/**
 * If `foo$` => make it just `foo`
 *
 * @ignore
 * @param {?} name
 * @return {?}
 */
function removeDollarAtTheEnd(name) {
    /** @type {?} */
    var lastCharIndex = name.length - 1;
    /** @type {?} */
    var dollarAtTheEnd = name.charCodeAt(lastCharIndex) === DOLLAR_CHAR_CODE;
    return dollarAtTheEnd ? name.slice(0, lastCharIndex) : name;
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Returns the type from an action instance/class.
 * @ignore
 * @param {?} action
 * @return {?}
 */
function getActionTypeFromInstance(action) {
    if (action.constructor && action.constructor.type) {
        return action.constructor.type;
    }
    return action.type;
}
/**
 * Matches a action
 * @ignore
 * @param {?} action1
 * @return {?}
 */
function actionMatcher(action1) {
    /** @type {?} */
    var type1 = getActionTypeFromInstance(action1);
    return (/**
     * @param {?} action2
     * @return {?}
     */
    function (action2) {
        return type1 === getActionTypeFromInstance(action2);
    });
}
/**
 * Set a deeply nested value. Example:
 *
 *   setValue({ foo: { bar: { eat: false } } },
 *      'foo.bar.eat', true) //=> { foo: { bar: { eat: true } } }
 *
 * While it traverses it also creates new objects from top down.
 *
 * @ignore
 * @type {?}
 */
var setValue = (/**
 * @param {?} obj
 * @param {?} prop
 * @param {?} val
 * @return {?}
 */
function (obj, prop, val) {
    obj = __assign({}, obj);
    /** @type {?} */
    var split = prop.split('.');
    /** @type {?} */
    var lastIndex = split.length - 1;
    split.reduce((/**
     * @param {?} acc
     * @param {?} part
     * @param {?} index
     * @return {?}
     */
    function (acc, part, index) {
        if (index === lastIndex) {
            acc[part] = val;
        }
        else {
            acc[part] = Array.isArray(acc[part]) ? __spread(acc[part]) : __assign({}, acc[part]);
        }
        return acc && acc[part];
    }), obj);
    return obj;
});
/**
 * Get a deeply nested value. Example:
 *
 *    getValue({ foo: bar: [] }, 'foo.bar') //=> []
 *
 * @ignore
 * @type {?}
 */
var getValue = (/**
 * @param {?} obj
 * @param {?} prop
 * @return {?}
 */
function (obj, prop) {
    return prop.split('.').reduce((/**
     * @param {?} acc
     * @param {?} part
     * @return {?}
     */
    function (acc, part) { return acc && acc[part]; }), obj);
});

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will grab actions that have just been dispatched as well as actions that have completed
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofAction() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    return ofActionOperator(allowedTypes);
}
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will ONLY grab actions that have just been dispatched
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofActionDispatched() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    return ofActionOperator(allowedTypes, ["DISPATCHED" /* Dispatched */]);
}
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will ONLY grab actions that have just been successfully completed
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofActionSuccessful() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    return ofActionOperator(allowedTypes, ["SUCCESSFUL" /* Successful */]);
}
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will ONLY grab actions that have just been canceled
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofActionCanceled() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    return ofActionOperator(allowedTypes, ["CANCELED" /* Canceled */]);
}
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will ONLY grab actions that have just been completed
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofActionCompleted() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    /** @type {?} */
    var allowedStatuses = [
        "SUCCESSFUL" /* Successful */,
        "CANCELED" /* Canceled */,
        "ERRORED" /* Errored */
    ];
    return ofActionOperator(allowedTypes, allowedStatuses, mapActionResult);
}
/**
 * RxJS operator for selecting out specific actions.
 *
 * This will ONLY grab actions that have just thrown an error
 * @param {...?} allowedTypes
 * @return {?}
 */
function ofActionErrored() {
    var allowedTypes = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        allowedTypes[_i] = arguments[_i];
    }
    return ofActionOperator(allowedTypes, ["ERRORED" /* Errored */]);
}
/**
 * @template T
 * @param {?} allowedTypes
 * @param {?=} statuses
 * @param {?=} mapOperator
 * @return {?}
 */
function ofActionOperator(allowedTypes, statuses, mapOperator) {
    if (mapOperator === void 0) { mapOperator = mapAction; }
    /** @type {?} */
    var allowedMap = createAllowedActionTypesMap(allowedTypes);
    /** @type {?} */
    var allowedStatusMap = statuses && createAllowedStatusesMap(statuses);
    return (/**
     * @param {?} o
     * @return {?}
     */
    function (o) {
        return o.pipe(filterStatus(allowedMap, allowedStatusMap), mapOperator());
    });
}
/**
 * @param {?} allowedTypes
 * @param {?=} allowedStatuses
 * @return {?}
 */
function filterStatus(allowedTypes, allowedStatuses) {
    return filter((/**
     * @param {?} ctx
     * @return {?}
     */
    function (ctx) {
        /** @type {?} */
        var actionType = (/** @type {?} */ (getActionTypeFromInstance(ctx.action)));
        /** @type {?} */
        var typeMatch = allowedTypes[actionType];
        /** @type {?} */
        var statusMatch = allowedStatuses ? allowedStatuses[ctx.status] : true;
        return typeMatch && statusMatch;
    }));
}
/**
 * @return {?}
 */
function mapActionResult() {
    return map((/**
     * @param {?} __0
     * @return {?}
     */
    function (_a) {
        var action = _a.action, status = _a.status, error = _a.error;
        return (/** @type {?} */ ({
            action: action,
            result: {
                successful: "SUCCESSFUL" /* Successful */ === status,
                canceled: "CANCELED" /* Canceled */ === status,
                error: error
            }
        }));
    }));
}
/**
 * @template T
 * @return {?}
 */
function mapAction() {
    return map((/**
     * @param {?} ctx
     * @return {?}
     */
    function (ctx) { return (/** @type {?} */ (ctx.action)); }));
}
/**
 * @param {?} types
 * @return {?}
 */
function createAllowedActionTypesMap(types) {
    return types.reduce((/**
     * @param {?} filterMap
     * @param {?} klass
     * @return {?}
     */
    function (filterMap, klass) {
        filterMap[(/** @type {?} */ (getActionTypeFromInstance(klass)))] = true;
        return filterMap;
    }), (/** @type {?} */ ({})));
}
/**
 * @param {?} statuses
 * @return {?}
 */
function createAllowedStatusesMap(statuses) {
    return statuses.reduce((/**
     * @param {?} filterMap
     * @param {?} status
     * @return {?}
     */
    function (filterMap, status) {
        filterMap[status] = true;
        return filterMap;
    }), (/** @type {?} */ ({})));
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var InternalNgxsExecutionStrategy = /** @class */ (function () {
    function InternalNgxsExecutionStrategy(_executionStrategy) {
        this._executionStrategy = _executionStrategy;
    }
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    InternalNgxsExecutionStrategy.prototype.enter = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        return this._executionStrategy.enter(func);
    };
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    InternalNgxsExecutionStrategy.prototype.leave = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        return this._executionStrategy.leave(func);
    };
    InternalNgxsExecutionStrategy.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    InternalNgxsExecutionStrategy.ctorParameters = function () { return [
        { type: undefined, decorators: [{ type: Inject, args: [NGXS_EXECUTION_STRATEGY,] }] }
    ]; };
    return InternalNgxsExecutionStrategy;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Returns operator that will run
 * `subscribe` outside of the ngxs execution context
 * @template T
 * @param {?} ngxsExecutionStrategy
 * @return {?}
 */
function leaveNgxs(ngxsExecutionStrategy) {
    return (/**
     * @param {?} source
     * @return {?}
     */
    function (source) {
        return new Observable((/**
         * @param {?} sink
         * @return {?}
         */
        function (sink) {
            return source.subscribe({
                next: /**
                 * @param {?} value
                 * @return {?}
                 */
                function (value) {
                    ngxsExecutionStrategy.leave((/**
                     * @return {?}
                     */
                    function () { return sink.next(value); }));
                },
                error: /**
                 * @param {?} error
                 * @return {?}
                 */
                function (error) {
                    ngxsExecutionStrategy.leave((/**
                     * @return {?}
                     */
                    function () { return sink.error(error); }));
                },
                complete: /**
                 * @return {?}
                 */
                function () {
                    ngxsExecutionStrategy.leave((/**
                     * @return {?}
                     */
                    function () { return sink.complete(); }));
                }
            });
        }));
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Custom Subject that ensures that subscribers are notified of values in the order that they arrived.
 * A standard Subject does not have this guarantee.
 * For example, given the following code:
 * ```typescript
 *   const subject = new Subject<string>();
 * subject.subscribe(value => {
 * if (value === 'start') subject.next('end');
 * });
 * subject.subscribe(value => { });
 * subject.next('start');
 * ```
 * When `subject` is a standard `Subject<T>` the second subscriber would recieve `end` and then `start`.
 * When `subject` is a `OrderedSubject<T>` the second subscriber would recieve `start` and then `end`.
 * @template T
 */
var  /**
 * Custom Subject that ensures that subscribers are notified of values in the order that they arrived.
 * A standard Subject does not have this guarantee.
 * For example, given the following code:
 * ```typescript
 *   const subject = new Subject<string>();
 * subject.subscribe(value => {
 * if (value === 'start') subject.next('end');
 * });
 * subject.subscribe(value => { });
 * subject.next('start');
 * ```
 * When `subject` is a standard `Subject<T>` the second subscriber would recieve `end` and then `start`.
 * When `subject` is a `OrderedSubject<T>` the second subscriber would recieve `start` and then `end`.
 * @template T
 */
OrderedSubject = /** @class */ (function (_super) {
    __extends(OrderedSubject, _super);
    function OrderedSubject() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._itemQueue = [];
        _this._busyPushingNext = false;
        return _this;
    }
    /**
     * @param {?=} value
     * @return {?}
     */
    OrderedSubject.prototype.next = /**
     * @param {?=} value
     * @return {?}
     */
    function (value) {
        if (this._busyPushingNext) {
            this._itemQueue.unshift((/** @type {?} */ (value)));
            return;
        }
        this._busyPushingNext = true;
        _super.prototype.next.call(this, value);
        while (this._itemQueue.length > 0) {
            /** @type {?} */
            var nextValue = this._itemQueue.pop();
            _super.prototype.next.call(this, nextValue);
        }
        this._busyPushingNext = false;
    };
    return OrderedSubject;
}(Subject));
/**
 * Internal Action stream that is emitted anytime an action is dispatched.
 */
var InternalActions = /** @class */ (function (_super) {
    __extends(InternalActions, _super);
    function InternalActions() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    InternalActions.decorators = [
        { type: Injectable }
    ];
    return InternalActions;
}(OrderedSubject));
/**
 * Action stream that is emitted anytime an action is dispatched.
 *
 * You can listen to this in services to react without stores.
 */
var Actions = /** @class */ (function (_super) {
    __extends(Actions, _super);
    function Actions(actions$, internalExecutionStrategy) {
        return _super.call(this, (/**
         * @param {?} observer
         * @return {?}
         */
        function (observer) {
            actions$
                .pipe(leaveNgxs(internalExecutionStrategy))
                .subscribe((/**
             * @param {?} res
             * @return {?}
             */
            function (res) { return observer.next(res); }), (/**
             * @param {?} err
             * @return {?}
             */
            function (err) { return observer.error(err); }), (/**
             * @return {?}
             */
            function () { return observer.complete(); }));
        })) || this;
    }
    Actions.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    Actions.ctorParameters = function () { return [
        { type: InternalActions },
        { type: InternalNgxsExecutionStrategy }
    ]; };
    return Actions;
}(Observable));

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Composes a array of functions from left to right. Example:
 *
 *      compose([fn, final])(state, action);
 *
 * then the funcs have a signature like:
 *
 *      function fn (state, action, next) {
 *          console.log('here', state, action, next);
 *          return next(state, action);
 *      }
 *
 *      function final (state, action) {
 *          console.log('here', state, action);
 *          return state;
 *      }
 *
 * the last function should not call `next`.
 *
 * @ignore
 * @type {?}
 */
var compose = (/**
 * @param {?} funcs
 * @return {?}
 */
function (funcs) { return (/**
 * @param {...?} args
 * @return {?}
 */
function () {
    var args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        args[_i] = arguments[_i];
    }
    /** @type {?} */
    var curr = (/** @type {?} */ (funcs.shift()));
    return curr.apply(void 0, __spread(args, [(/**
         * @param {...?} nextArgs
         * @return {?}
         */
        function () {
            var nextArgs = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                nextArgs[_i] = arguments[_i];
            }
            return compose(funcs).apply(void 0, __spread(nextArgs));
        })]));
}); });

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * BehaviorSubject of the entire state.
 * @ignore
 */
var StateStream = /** @class */ (function (_super) {
    __extends(StateStream, _super);
    function StateStream() {
        return _super.call(this, {}) || this;
    }
    StateStream.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    StateStream.ctorParameters = function () { return []; };
    return StateStream;
}(BehaviorSubject));

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Plugin manager class
 * @ignore
 */
var PluginManager = /** @class */ (function () {
    function PluginManager(_parentManager, _plugins) {
        this._parentManager = _parentManager;
        this._plugins = _plugins;
        this.plugins = [];
        this.register();
    }
    /**
     * @private
     * @return {?}
     */
    PluginManager.prototype.register = /**
     * @private
     * @return {?}
     */
    function () {
        var _a;
        if (!this._plugins) {
            return;
        }
        this.plugins = this._plugins.map((/**
         * @param {?} plugin
         * @return {?}
         */
        function (plugin) {
            if (plugin.handle) {
                return plugin.handle.bind(plugin);
            }
            else {
                return plugin;
            }
        }));
        if (this._parentManager) {
            (_a = this._parentManager.plugins).push.apply(_a, __spread(this.plugins));
        }
    };
    PluginManager.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    PluginManager.ctorParameters = function () { return [
        { type: PluginManager, decorators: [{ type: Optional }, { type: SkipSelf }] },
        { type: Array, decorators: [{ type: Inject, args: [NGXS_PLUGINS,] }, { type: Optional }] }
    ]; };
    return PluginManager;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * 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.
 */
var InternalDispatchedActionResults = /** @class */ (function (_super) {
    __extends(InternalDispatchedActionResults, _super);
    function InternalDispatchedActionResults() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    InternalDispatchedActionResults.decorators = [
        { type: Injectable }
    ];
    return InternalDispatchedActionResults;
}(Subject));
var InternalDispatcher = /** @class */ (function () {
    function InternalDispatcher(_errorHandler, _actions, _actionResults, _pluginManager, _stateStream, _ngxsExecutionStrategy) {
        this._errorHandler = _errorHandler;
        this._actions = _actions;
        this._actionResults = _actionResults;
        this._pluginManager = _pluginManager;
        this._stateStream = _stateStream;
        this._ngxsExecutionStrategy = _ngxsExecutionStrategy;
    }
    /**
     * Dispatches event(s).
     */
    /**
     * Dispatches event(s).
     * @param {?} actionOrActions
     * @return {?}
     */
    InternalDispatcher.prototype.dispatch = /**
     * Dispatches event(s).
     * @param {?} actionOrActions
     * @return {?}
     */
    function (actionOrActions) {
        var _this = this;
        /** @type {?} */
        var result = this._ngxsExecutionStrategy.enter((/**
         * @return {?}
         */
        function () {
            return _this.dispatchByEvents(actionOrActions);
        }));
        result.subscribe({
            error: (/**
             * @param {?} error
             * @return {?}
             */
            function (error) {
                return _this._ngxsExecutionStrategy.leave((/**
                 * @return {?}
                 */
                function () { return _this._errorHandler.handleError(error); }));
            })
        });
        return result.pipe(leaveNgxs(this._ngxsExecutionStrategy));
    };
    /**
     * @private
     * @param {?} actionOrActions
     * @return {?}
     */
    InternalDispatcher.prototype.dispatchByEvents = /**
     * @private
     * @param {?} actionOrActions
     * @return {?}
     */
    function (actionOrActions) {
        var _this = this;
        if (Array.isArray(actionOrActions)) {
            return forkJoin(actionOrActions.map((/**
             * @param {?} a
             * @return {?}
             */
            function (a) { return _this.dispatchSingle(a); })));
        }
        else {
            return this.dispatchSingle(actionOrActions);
        }
    };
    /**
     * @private
     * @param {?} action
     * @return {?}
     */
    InternalDispatcher.prototype.dispatchSingle = /**
     * @private
     * @param {?} action
     * @return {?}
     */
    function (action) {
        var _this = this;
        /** @type {?} */
        var prevState = this._stateStream.getValue();
        /** @type {?} */
        var plugins = this._pluginManager.plugins;
        return ((/** @type {?} */ (compose(__spread(plugins, [
            (/**
             * @param {?} nextState
             * @param {?} nextAction
             * @return {?}
             */
            function (nextState, nextAction) {
                if (nextState !== prevState) {
                    _this._stateStream.next(nextState);
                }
                /** @type {?} */
                var actionResult$ = _this.getActionResultStream(nextAction);
                actionResult$.subscribe((/**
                 * @param {?} ctx
                 * @return {?}
                 */
                function (ctx) { return _this._actions.next(ctx); }));
                _this._actions.next({ action: nextAction, status: "DISPATCHED" /* Dispatched */ });
                return _this.createDispatchObservable(actionResult$);
            })
        ]))(prevState, action)))).pipe(shareReplay());
    };
    /**
     * @private
     * @param {?} action
     * @return {?}
     */
    InternalDispatcher.prototype.getActionResultStream = /**
     * @private
     * @param {?} action
     * @return {?}
     */
    function (action) {
        return this._actionResults.pipe(filter((/**
         * @param {?} ctx
         * @return {?}
         */
        function (ctx) { return ctx.action === action && ctx.status !== "DISPATCHED" /* Dispatched */; })), take(1), shareReplay());
    };
    /**
     * @private
     * @param {?} actionResult$
     * @return {?}
     */
    InternalDispatcher.prototype.createDispatchObservable = /**
     * @private
     * @param {?} actionResult$
     * @return {?}
     */
    function (actionResult$) {
        var _this = this;
        return actionResult$
            .pipe(exhaustMap((/**
         * @param {?} ctx
         * @return {?}
         */
        function (ctx) {
            switch (ctx.status) {
                case "SUCCESSFUL" /* Successful */:
                    return of(_this._stateStream.getValue());
                case "ERRORED" /* Errored */:
                    return throwError(ctx.error);
                default:
                    return empty();
            }
        })))
            .pipe(shareReplay());
    };
    InternalDispatcher.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    InternalDispatcher.ctorParameters = function () { return [
        { type: ErrorHandler },
        { type: InternalActions },
        { type: InternalDispatchedActionResults },
        { type: PluginManager },
        { type: StateStream },
        { type: InternalNgxsExecutionStrategy }
    ]; };
    return InternalDispatcher;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @param {?} a
 * @param {?} b
 * @return {?}
 */
function defaultEqualityCheck(a, b) {
    return a === b;
}
/**
 * @param {?} equalityCheck
 * @param {?} prev
 * @param {?} next
 * @return {?}
 */
function areArgumentsShallowlyEqual(equalityCheck, prev, next) {
    if (prev === null || next === null || prev.length !== next.length) {
        return false;
    }
    // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible.
    /** @type {?} */
    var length = prev.length;
    for (var i = 0; i < length; i++) {
        if (!equalityCheck(prev[i], next[i])) {
            return false;
        }
    }
    return true;
}
/**
 * Memoize a function on its last inputs only.
 * Oringinally from: https://github.com/reduxjs/reselect/blob/master/src/index.js
 *
 * @ignore
 * @template T
 * @param {?} func
 * @param {?=} equalityCheck
 * @return {?}
 */
function memoize(func, equalityCheck) {
    if (equalityCheck === void 0) { equalityCheck = defaultEqualityCheck; }
    /** @type {?} */
    var lastArgs = null;
    /** @type {?} */
    var lastResult = null;
    // we reference arguments instead of spreading them for performance reasons
    /**
     * @return {?}
     */
    function memoized() {
        if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) {
            // apply arguments instead of spreading for performance.
            lastResult = ((/** @type {?} */ (func))).apply(null, arguments);
        }
        lastArgs = arguments;
        return lastResult;
    }
    ((/** @type {?} */ (memoized))).reset = (/**
     * @return {?}
     */
    function () {
        // The hidden (for now) ability to reset the memoization
        lastArgs = null;
        lastResult = null;
    });
    return (/** @type {?} */ (memoized));
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @return {?}
 */
function _isAngularInTestMode() {
    /** @type {?} */
    var platformRef = getPlatform();
    if (!platformRef)
        return false;
    /** @type {?} */
    var compilerOptions = platformRef.injector.get(COMPILER_OPTIONS, null);
    if (!compilerOptions)
        return false;
    /** @type {?} */
    var isInTestMode = compilerOptions.some((/**
     * @param {?} item
     * @return {?}
     */
    function (item) {
        /** @type {?} */
        var providers = (item && item.providers) || [];
        return providers.some((/**
         * @param {?} provider
         * @return {?}
         */
        function (provider) {
            return ((provider && provider.provide && provider.provide.name === 'MockNgModuleResolver') ||
                false);
        }));
    }));
    return isInTestMode;
}
/** @type {?} */
var isAngularInTestMode = memoize(_isAngularInTestMode);

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ConfigValidator = /** @class */ (function () {
    function ConfigValidator(_config) {
        this._config = _config;
    }
    /**
     * @return {?}
     */
    ConfigValidator.prototype.verifyDevMode = /**
     * @return {?}
     */
    function () {
        if (isAngularInTestMode()) {
            return;
        }
        /** @type {?} */
        var isNgxsDevMode = this._config.developmentMode;
        /** @type {?} */
        var isNgDevMode = isDevMode();
        /** @type {?} */
        var incorrectProduction = !isNgDevMode && isNgxsDevMode;
        /** @type {?} */
        var incorrectDevelopment = isNgDevMode && !isNgxsDevMode;
        /** @type {?} */
        var example = 'NgxsModule.forRoot(states, { developmentMode: !environment.production })';
        if (incorrectProduction) {
            console.warn('Angular is running in production mode but NGXS is still running in the development mode!\n', 'Please set developmentMode to false on the NgxsModule options when in production mode.\n', example);
        }
        else if (incorrectDevelopment) {
            console.warn('RECOMMENDATION: Set developmentMode to true on the NgxsModule when Angular is running in development mode.\n', example);
        }
    };
    ConfigValidator.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    ConfigValidator.ctorParameters = function () { return [
        { type: NgxsConfig }
    ]; };
    return ConfigValidator;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Object freeze code
 * https://github.com/jsdf/deep-freeze
 * @type {?}
 */
var deepFreeze = (/**
 * @param {?} o
 * @return {?}
 */
function (o) {
    Object.freeze(o);
    /** @type {?} */
    var oIsFunction = typeof o === 'function';
    /** @type {?} */
    var hasOwnProp = Object.prototype.hasOwnProperty;
    Object.getOwnPropertyNames(o).forEach((/**
     * @param {?} prop
     * @return {?}
     */
    function (prop) {
        if (hasOwnProp.call(o, prop) &&
            (oIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true) &&
            o[prop] !== null &&
            (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
            !Object.isFrozen(o[prop])) {
            deepFreeze(o[prop]);
        }
    }));
    return o;
});

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * State Context factory class
 * @ignore
 */
var InternalStateOperations = /** @class */ (function () {
    function InternalStateOperations(_stateStream, _dispatcher, _config, configValidator) {
        this._stateStream = _stateStream;
        this._dispatcher = _dispatcher;
        this._config = _config;
        configValidator.verifyDevMode();
    }
    /**
     * Returns the root state operators.
     */
    /**
     * Returns the root state operators.
     * @return {?}
     */
    InternalStateOperations.prototype.getRootStateOperations = /**
     * Returns the root state operators.
     * @return {?}
     */
    function () {
        var _this = this;
        /** @type {?} */
        var rootStateOperations = {
            getState: (/**
             * @return {?}
             */
            function () { return _this._stateStream.getValue(); }),
            setState: (/**
             * @param {?} newState
             * @return {?}
             */
            function (newState) { return _this._stateStream.next(newState); }),
            dispatch: (/**
             * @param {?} actions
             * @return {?}
             */
            function (actions) { return _this._dispatcher.dispatch(actions); })
        };
        if (this._config.developmentMode) {
            return this.ensureStateAndActionsAreImmutable(rootStateOperations);
        }
        return rootStateOperations;
    };
    /**
     * @private
     * @param {?} root
     * @return {?}
     */
    InternalStateOperations.prototype.ensureStateAndActionsAreImmutable = /**
     * @private
     * @param {?} root
     * @return {?}
     */
    function (root) {
        return {
            getState: (/**
             * @return {?}
             */
            function () { return root.getState(); }),
            setState: (/**
             * @param {?} value
             * @return {?}
             */
            function (value) {
                /** @type {?} */
                var frozenValue = deepFreeze(value);
                return root.setState(frozenValue);
            }),
            dispatch: (/**
             * @param {?} actions
             * @return {?}
             */
            function (actions) {
                return root.dispatch(actions);
            })
        };
    };
    /**
     * @param {?} results
     * @return {?}
     */
    InternalStateOperations.prototype.setStateToTheCurrentWithNew = /**
     * @param {?} results
     * @return {?}
     */
    function (results) {
        /** @type {?} */
        var stateOperations = this.getRootStateOperations();
        // Get our current stream
        /** @type {?} */
        var currentState = stateOperations.getState();
        // Set the state to the current + new
        stateOperations.setState(__assign({}, currentState, results.defaults));
    };
    InternalStateOperations.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    InternalStateOperations.ctorParameters = function () { return [
        { type: StateStream },
        { type: InternalDispatcher },
        { type: NgxsConfig },
        { type: ConfigValidator }
    ]; };
    return InternalStateOperations;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @template T
 * @param {?} val
 * @return {?}
 */
function simplePatch(val) {
    return (/**
     * @param {?} existingState
     * @return {?}
     */
    function (existingState) {
        /** @type {?} */
        var isArray = Array.isArray(val);
        /** @type {?} */
        var isPrimitive = typeof val !== 'object';
        if (isArray) {
            throw new Error('Patching arrays is not supported.');
        }
        if (isPrimitive) {
            throw new Error('Patching primitives is not supported.');
        }
        /** @type {?} */
        var newState = __assign({}, ((/** @type {?} */ (existingState))));
        for (var k in val) {
            newState[k] = val[k];
        }
        return (/** @type {?} */ (newState));
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * State Context factory class
 * @ignore
 */
var StateContextFactory = /** @class */ (function () {
    function StateContextFactory(_internalStateOperations) {
        this._internalStateOperations = _internalStateOperations;
    }
    /**
     * Create the state context
     */
    /**
     * Create the state context
     * @template T
     * @param {?} metadata
     * @return {?}
     */
    StateContextFactory.prototype.createStateContext = /**
     * Create the state context
     * @template T
     * @param {?} metadata
     * @return {?}
     */
    function (metadata) {
        /** @type {?} */
        var root = this._internalStateOperations.getRootStateOperations();
        /**
         * @param {?} currentAppState
         * @return {?}
         */
        function getState(currentAppState) {
            return getValue(currentAppState, metadata.depth);
        }
        /**
         * @param {?} currentAppState
         * @param {?} newValue
         * @return {?}
         */
        function setStateValue(currentAppState, newValue) {
            /** @type {?} */
            var newAppState = setValue(currentAppState, metadata.depth, newValue);
            root.setState(newAppState);
            return newAppState;
            // In doing this refactoring I noticed that there is a 'bug' where the
            // application state is returned instead of this state slice.
            // This has worked this way since the beginning see:
            // https://github.com/ngxs/store/blame/324c667b4b7debd8eb979006c67ca0ae347d88cd/src/state-factory.ts
            // This needs to be fixed, but is a 'breaking' change.
            // I will do this fix in a subsequent PR and we can decide how to handle it.
        }
        /**
         * @param {?} currentAppState
         * @param {?} stateOperator
         * @return {?}
         */
        function setStateFromOperator(currentAppState, stateOperator) {
            /** @type {?} */
            var local = getState(currentAppState);
            /** @type {?} */
            var newValue = stateOperator(local);
            return setStateValue(currentAppState, newValue);
        }
        /**
         * @param {?} value
         * @return {?}
         */
        function isStateOperator(value) {
            return typeof value === 'function';
        }
        return {
            getState: /**
             * @return {?}
             */
            function () {
                /** @type {?} */
                var currentAppState = root.getState();
                return getState(currentAppState);
            },
            patchState: /**
             * @param {?} val
             * @return {?}
             */
            function (val) {
                /** @type {?} */
                var currentAppState = root.getState();
                /** @type {?} */
                var patchOperator = simplePatch(val);
                return setStateFromOperator(currentAppState, patchOperator);
            },
            setState: /**
             * @param {?} val
             * @return {?}
             */
            function (val) {
                /** @type {?} */
                var currentAppState = root.getState();
                return isStateOperator(val)
                    ? setStateFromOperator(currentAppState, val)
                    : setStateValue(currentAppState, val);
            },
            dispatch: /**
             * @param {?} actions
             * @return {?}
             */
            function (actions) {
                return root.dispatch(actions);
            }
        };
    };
    StateContextFactory.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    StateContextFactory.ctorParameters = function () { return [
        { type: InternalStateOperations }
    ]; };
    return StateContextFactory;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @abstract
 */
var StoreValidators = /** @class */ (function () {
    function StoreValidators() {
    }
    /**
     * @param {?} name
     * @return {?}
     */
    StoreValidators.stateNameErrorMessage = /**
     * @param {?} name
     * @return {?}
     */
    function (name) {
        return name + " is not a valid state name. It needs to be a valid object property name.";
    };
    /**
     * @param {?} name
     * @return {?}
     */
    StoreValidators.checkCorrectStateName = /**
     * @param {?} name
     * @return {?}
     */
    function (name) {
        if (!name) {
            throw new Error("States must register a 'name' property");
        }
        if (!this.stateNameRegex.test(name)) {
            throw new Error(this.stateNameErrorMessage(name));
        }
    };
    /**
     * @param {?} state
     * @param {?} statesByName
     * @return {?}
     */
    StoreValidators.checkStateNameIsUnique = /**
     * @param {?} state
     * @param {?} statesByName
     * @return {?}
     */
    function (state, statesByName) {
        /** @type {?} */
        var meta = this.getValidStateMeta(state);
        /** @type {?} */
        var stateName = (/** @type {?} */ ((/** @type {?} */ (meta)).name));
        /** @type {?} */
        var existingState = statesByName[stateName];
        if (existingState && existingState !== state) {
            throw new Error("State name '" + stateName + "' from " + state.name + " already exists in " + existingState.name);
        }
        return stateName;
    };
    /**
     * @param {?} state
     * @return {?}
     */
    StoreValidators.getValidStateMeta = /**
     * @param {?} state
     * @return {?}
     */
    function (state) {
        /** @type {?} */
        var meta = getStoreMetadata(state);
        if (!meta) {
            throw new Error('States must be decorated with @State() decorator');
        }
        return meta;
    };
    StoreValidators.stateNameRegex = new RegExp('^[a-zA-Z0-9_]+$');
    return StoreValidators;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * State factory class
 * @ignore
 */
var StateFactory = /** @class */ (function () {
    function StateFactory(_injector, _config, _parentFactory, _actions, _actionResults, _stateContextFactory, _internalStateOperations) {
        this._injector = _injector;
        this._config = _config;
        this._parentFactory = _parentFactory;
        this._actions = _actions;
        this._actionResults = _actionResults;
        this._stateContextFactory = _stateContextFactory;
        this._internalStateOperations = _internalStateOperations;
        this._connected = false;
        this._states = [];
        this._statesByName = {};
    }
    Object.defineProperty(StateFactory.prototype, "states", {
        get: /**
         * @return {?}
         */
        function () {
            return this._parentFactory ? this._parentFactory.states : this._states;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StateFactory.prototype, "statesByName", {
        get: /**
         * @return {?}
         */
        function () {
            return this._parentFactory ? this._parentFactory.statesByName : this._statesByName;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StateFactory.prototype, "stateTreeRef", {
        get: /**
         * @private
         * @return {?}
         */
        function () {
            return this._internalStateOperations.getRootStateOperations().getState();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @private
     * @param {?} defaults
     * @return {?}
     */
    StateFactory.cloneDefaults = /**
     * @private
     * @param {?} defaults
     * @return {?}
     */
    function (defaults) {
        /** @type {?} */
        var value = {};
        if (Array.isArray(defaults)) {
            value = __spread(defaults);
        }
        else if (isObject(defaults)) {
            value = __assign({}, defaults);
        }
        else if (defaults === undefined) {
            value = {};
        }
        else {
            value = defaults;
        }
        return value;
    };
    /**
     * @private
     * @param {?} stateClasses
     * @return {?}
     */
    StateFactory.checkStatesAreValid = /**
     * @private
     * @param {?} stateClasses
     * @return {?}
     */
    function (stateClasses) {
        stateClasses.forEach(StoreValidators.getValidStateMeta);
    };
    /**
     * Add a new state to the global defs.
     */
    /**
     * Add a new state to the global defs.
     * @param {?} stateClasses
     * @return {?}
     */
    StateFactory.prototype.add = /**
     * Add a new state to the global defs.
     * @param {?} stateClasses
     * @return {?}
     */
    function (stateClasses) {
        var e_1, _a;
        StateFactory.checkStatesAreValid(stateClasses);
        var newStates = this.addToStatesMap(stateClasses).newStates;
        if (!newStates.length)
            return [];
        /** @type {?} */
        var stateGraph = buildGraph(newStates);
        /** @type {?} */
        var sortedStates = topologicalSort(stateGraph);
        /** @type {?} */
        var depths = findFullParentPath(stateGraph);
        /** @type {?} */
        var nameGraph = nameToState(newStates);
        /** @type {?} */
        var bootstrappedStores = [];
        try {
            for (var sortedStates_1 = __values(sortedStates), sortedStates_1_1 = sortedStates_1.next(); !sortedStates_1_1.done; sortedStates_1_1 = sortedStates_1.next()) {
                var name_1 = sortedStates_1_1.value;
                /** @type {?} */
                var stateClass = nameGraph[name_1];
                /** @type {?} */
                var depth = depths[name_1];
                /** @type {?} */
                var meta = (/** @type {?} */ (stateClass[META_KEY]));
                this.addRuntimeInfoToMeta(meta, depth);
                /** @type {?} */
                var stateMap = {
                    name: name_1,
                    depth: depth,
                    actions: meta.actions,
                    instance: this._injector.get(stateClass),
                    defaults: StateFactory.cloneDefaults(meta.defaults)
                };
                // ensure our store hasn't already been added
                // but don't throw since it could be lazy
                // loaded from different paths
                if (!this.hasBeenMountedAndBootstrapped(name_1, depth)) {
                    bootstrappedStores.push(stateMap);
                }
                this.states.push(stateMap);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (sortedStates_1_1 && !sortedStates_1_1.done && (_a = sortedStates_1.return)) _a.call(sortedStates_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return bootstrappedStores;
    };
    /**
     * Add a set of states to the store and return the defaults
     */
    /**
     * Add a set of states to the store and return the defaults
     * @param {?} stateClasses
     * @return {?}
     */
    StateFactory.prototype.addAndReturnDefaults = /**
     * Add a set of states to the store and return the defaults
     * @param {?} stateClasses
     * @return {?}
     */
    function (stateClasses) {
        /** @type {?} */
        var classes = stateClasses || [];
        /** @type {?} */
        var states = this.add(classes);
        /** @type {?} */
        var defaults = states.reduce((/**
         * @param {?} result
         * @param {?} meta
         * @return {?}
         */
        function (result, meta) { return setValue(result, meta.depth, meta.defaults); }), {});
        return { defaults: defaults, states: states };
    };
    /**
     * Bind the actions to the handlers
     */
    /**
     * Bind the actions to the handlers
     * @return {?}
     */
    StateFactory.prototype.connectActionHandlers = /**
     * Bind the actions to the handlers
     * @return {?}
     */
    function () {
        var _this = this;
        if (this._connected)
            return;
        this._actions
            .pipe(filter((/**
         * @param {?} ctx
         * @return {?}
         */
        function (ctx) { return ctx.status === "DISPATCHED" /* Dispatched */; })), mergeMap((/**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var action = _a.action;
            return _this.invokeActions(_this._actions, (/** @type {?} */ (action))).pipe(map((/**
             * @return {?}
             */
            function () { return (/** @type {?} */ ({ action: action, status: "SUCCESSFUL" /* Successful */ })); })), defaultIfEmpty((/** @type {?} */ ({ action: action, status: "CANCELED" /* Canceled */ }))), catchError((/**
             * @param {?} error
             * @return {?}
             */
            function (error) {
                return of((/** @type {?} */ ({ action: action, status: "ERRORED" /* Errored */, error: error })));
            })));
        })))
            .subscribe((/**
         * @param {?} ctx
         * @return {?}
         */
        function (ctx) { return _this._actionResults.next(ctx); }));
        this._connected = true;
    };
    /**
     * Invoke actions on the states.
     */
    /**
     * Invoke actions on the states.
     * @param {?} actions$
     * @param {?} action
     * @return {?}
     */
    StateFactory.prototype.invokeActions = /**
     * Invoke actions on the states.
     * @param {?} actions$
     * @param {?} action
     * @return {?}
     */
    function (actions$, action) {
        var e_2, _a, e_3, _b;
        /** @type {?} */
        var results = [];
        try {
            for (var _c = __values(this.states), _d = _c.next(); !_d.done; _d = _c.next()) {
                var metadata = _d.value;
                /** @type {?} */
                var type = (/** @type {?} */ (getActionTypeFromInstance(action)));
                /** @type {?} */
                var actionMetas = metadata.actions[type];
                if (actionMetas) {
                    try {
                        for (var actionMetas_1 = __values(actionMetas), actionMetas_1_1 = actionMetas_1.next(); !actionMetas_1_1.done; actionMetas_1_1 = actionMetas_1.next()) {
                            var actionMeta = actionMetas_1_1.value;
                            /** @type {?} */
                            var stateContext = this._stateContextFactory.createStateContext(metadata);
                            try {
                                /** @type {?} */
                                var result = metadata.instance[actionMeta.fn](stateContext, action);
                                if (result instanceof Promise) {
                                    result = from(result);
                                }
                                if (result instanceof Observable) {
                                    result = result.pipe(actionMeta.options.cancelUncompleted
                                        ? // todo: ofActionDispatched should be used with action class
                                            takeUntil(actions$.pipe(ofActionDispatched((/** @type {?} */ (action)))))
                                        : map((/**
                                         * @param {?} r
                                         * @return {?}
                                         */
                                        function (r) { return r; }))); // map acts like a noop
                                }
                                else {
                                    result = of({}).pipe(shareReplay());
                                }
                                results.push(result);
                            }
                            catch (e) {
                                results.push(throwError(e));
                            }
                        }
                    }
                    catch (e_3_1) { e_3 = { error: e_3_1 }; }
                    finally {
                        try {
                            if (actionMetas_1_1 && !actionMetas_1_1.done && (_b = actionMetas_1.return)) _b.call(actionMetas_1);
                        }
                        finally { if (e_3) throw e_3.error; }
                    }
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
            }
            finally { if (e_2) throw e_2.error; }
        }
        if (!results.length) {
            results.push(of({}));
        }
        return forkJoin(results);
    };
    /**
     * @private
     * @param {?} stateClasses
     * @return {?}
     */
    StateFactory.prototype.addToStatesMap = /**
     * @private
     * @param {?} stateClasses
     * @return {?}
     */
    function (stateClasses) {
        var e_4, _a;
        /** @type {?} */
        var newStates = [];
        /** @type {?} */
        var statesMap = this.statesByName;
        try {
            for (var stateClasses_1 = __values(stateClasses), stateClasses_1_1 = stateClasses_1.next(); !stateClasses_1_1.done; stateClasses_1_1 = stateClasses_1.next()) {
                var stateClass = stateClasses_1_1.value;
                /** @type {?} */
                var stateName = StoreValidators.checkStateNameIsUnique(stateClass, statesMap);
                /** @type {?} */
                var unmountedState = !statesMap[stateName];
                if (unmountedState) {
                    newStates.push(stateClass);
                    statesMap[stateName] = stateClass;
                }
            }
        }
        catch (e_4_1) { e_4 = { error: e_4_1 }; }
        finally {
            try {
                if (stateClasses_1_1 && !stateClasses_1_1.done && (_a = stateClasses_1.return)) _a.call(stateClasses_1);
            }
            finally { if (e_4) throw e_4.error; }
        }
        return { newStates: newStates };
    };
    /**
     * @private
     * @param {?} meta
     * @param {?} depth
     * @return {?}
     */
    StateFactory.prototype.addRuntimeInfoToMeta = /**
     * @private
     * @param {?} meta
     * @param {?} depth
     * @return {?}
     */
    function (meta, depth) {
        meta.path = depth;
        meta.selectFromAppState = propGetter(depth.split('.'), this._config);
    };
    /**
     * @description
     * the method checks if the state has already been added to the tree
     * and completed the life cycle
     * @param name
     * @param path
     */
    /**
     * \@description
     * the method checks if the state has already been added to the tree
     * and completed the life cycle
     * @private
     * @param {?} name
     * @param {?} path
     * @return {?}
     */
    StateFactory.prototype.hasBeenMountedAndBootstrapped = /**
     * \@description
     * the method checks if the state has already been added to the tree
     * and completed the life cycle
     * @private
     * @param {?} name
     * @param {?} path
     * @return {?}
     */
    function (name, path) {
        /** @type {?} */
        var valueIsBootstrapped = getValue(this.stateTreeRef, path) !== undefined;
        return this.statesByName[name] && valueIsBootstrapped;
    };
    StateFactory.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    StateFactory.ctorParameters = function () { return [
        { type: Injector },
        { type: NgxsConfig },
        { type: StateFactory, decorators: [{ type: Optional }, { type: SkipSelf }] },
        { type: InternalActions },
        { type: InternalDispatchedActionResults },
        { type: StateContextFactory },
        { type: InternalStateOperations }
    ]; };
    return StateFactory;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var LifecycleStateManager = /** @class */ (function () {
    function LifecycleStateManager(internalStateOperations, stateContextFactory, bootstrapper) {
        this.internalStateOperations = internalStateOperations;
        this.stateContextFactory = stateContextFactory;
        this.bootstrapper = bootstrapper;
    }
    /**
     * @template T
     * @param {?} action
     * @param {?} results
     * @return {?}
     */
    LifecycleStateManager.prototype.ngxsBootstrap = /**
     * @template T
     * @param {?} action
     * @param {?} results
     * @return {?}
     */
    function (action, results) {
        var _this = this;
        this.internalStateOperations
            .getRootStateOperations()
            .dispatch(action)
            .pipe(filter((/**
         * @return {?}
         */
        function () { return !!results; })), tap((/**
         * @return {?}
         */
        function () { return _this.invokeInit((/** @type {?} */ (results)).states); })), mergeMap((/**
         * @return {?}
         */
        function () { return _this.bootstrapper.appBootstrapped$; })), filter((/**
         * @param {?} appBootstrapped
         * @return {?}
         */
        function (appBootstrapped) { return !!appBootstrapped; })))
            .subscribe((/**
         * @return {?}
         */
        function () {
            _this.invokeBootstrap((/** @type {?} */ (results)).states);
        }));
    };
    /**
     * Invoke the init function on the states.
     */
    /**
     * Invoke the init function on the states.
     * @param {?} stateMetadatas
     * @return {?}
     */
    LifecycleStateManager.prototype.invokeInit = /**
     * Invoke the init function on the states.
     * @param {?} stateMetadatas
     * @return {?}
     */
    function (stateMetadatas) {
        this.invokeLifecycleHooks(stateMetadatas, "ngxsOnInit" /* NgxsOnInit */);
    };
    /**
     * Invoke the bootstrap function on the states.
     */
    /**
     * Invoke the bootstrap function on the states.
     * @param {?} stateMetadatas
     * @return {?}
     */
    LifecycleStateManager.prototype.invokeBootstrap = /**
     * Invoke the bootstrap function on the states.
     * @param {?} stateMetadatas
     * @return {?}
     */
    function (stateMetadatas) {
        this.invokeLifecycleHooks(stateMetadatas, "ngxsAfterBootstrap" /* NgxsAfterBootstrap */);
    };
    /**
     * @private
     * @param {?} stateMetadatas
     * @param {?} hook
     * @return {?}
     */
    LifecycleStateManager.prototype.invokeLifecycleHooks = /**
     * @private
     * @param {?} stateMetadatas
     * @param {?} hook
     * @return {?}
     */
    function (stateMetadatas, hook) {
        var e_1, _a;
        try {
            for (var stateMetadatas_1 = __values(stateMetadatas), stateMetadatas_1_1 = stateMetadatas_1.next(); !stateMetadatas_1_1.done; stateMetadatas_1_1 = stateMetadatas_1.next()) {
                var metadata = stateMetadatas_1_1.value;
                /** @type {?} */
                var instance = metadata.instance;
                if (instance[hook]) {
                    /** @type {?} */
                    var stateContext = this.stateContextFactory.createStateContext(metadata);
                    (/** @type {?} */ (instance[hook]))(stateContext);
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (stateMetadatas_1_1 && !stateMetadatas_1_1.done && (_a = stateMetadatas_1.return)) _a.call(stateMetadatas_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
    };
    LifecycleStateManager.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    LifecycleStateManager.ctorParameters = function () { return [
        { type: InternalStateOperations },
        { type: StateContextFactory },
        { type: NgxsBootstrapper }
    ]; };
    return LifecycleStateManager;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Function for creating a selector
 * @template T
 * @param {?} selectors The selectors to use to create the arguments of this function
 * @param {?} originalFn The original function being made into a selector
 * @param {?=} creationMetadata
 * @return {?}
 */
function createSelector(selectors, originalFn, creationMetadata) {
    /** @type {?} */
    var wrappedFn = (/** @type {?} */ ((/**
     * @param {...?} args
     * @return {?}
     */
    function wrappedSelectorFn() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        /** @type {?} */
        var returnValue = originalFn.apply(void 0, __spread(args));
        if (returnValue instanceof Function) {
            /** @type {?} */
            var innerMemoizedFn = memoize.apply(null, [returnValue]);
            return innerMemoizedFn;
        }
        return returnValue;
    })));
    /** @type {?} */
    var memoizedFn = memoize(wrappedFn);
    /** @type {?} */
    var containerClass = creationMetadata && creationMetadata.containerClass;
    /** @type {?} */
    var fn = (/**
     * @param {?} state
     * @return {?}
     */
    function (state) {
        /** @type {?} */
        var results = [];
        /** @type {?} */
        var selectorsToApply = [];
        if (containerClass) {
            // If we are on a state class, add it as the first selector parameter
            /** @type {?} */
            var metadata = getStoreMetadata(containerClass);
            if (metadata) {
                selectorsToApply.push(containerClass);
            }
        }
        if (selectors) {
            selectorsToApply.push.apply(selectorsToApply, __spread(selectors));
        }
        // Determine arguments from the app state using the selectors
        results.push.apply(results, __spread(selectorsToApply.map((/**
         * @param {?} a
         * @return {?}
         */
        function (a) { return getSelectorFn(a)(state); }))));
        // if the lambda tries to access a something on the
        // state that doesn't exist, it will throw a TypeError.
        // since this is quite usual behaviour, we simply return undefined if so.
        try {
            return memoizedFn.apply(void 0, __spread(results));
        }
        catch (ex) {
            if (ex instanceof TypeError) {
                return undefined;
            }
            throw ex;
        }
    });
    /** @type {?} */
    var selectorMetaData = ensureSelectorMetadata(memoizedFn);
    selectorMetaData.originalFn = originalFn;
    selectorMetaData.selectFromAppState = fn;
    if (creationMetadata) {
        selectorMetaData.containerClass = creationMetadata.containerClass;
        selectorMetaData.selectorName = creationMetadata.selectorName;
    }
    return memoizedFn;
}
/**
 * This function gets the selector function to be used to get the selected slice from the app state
 * @ignore
 * @param {?} selector
 * @return {?}
 */
function getSelectorFn(selector) {
    /** @type {?} */
    var metadata = getSelectorMetadata(selector) || getStoreMetadata(selector);
    return (metadata && metadata.selectFromAppState) || selector;
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var Store = /** @class */ (function () {
    function Store(_stateStream, _internalStateOperations, _config, _internalExecutionStrategy) {
        this._stateStream = _stateStream;
        this._internalStateOperations = _internalStateOperations;
        this._config = _config;
        this._internalExecutionStrategy = _internalExecutionStrategy;
        this._stateStream.next(this._config.defaultsState);
    }
    /**
     * Dispatches event(s).
     */
    /**
     * Dispatches event(s).
     * @param {?} event
     * @return {?}
     */
    Store.prototype.dispatch = /**
     * Dispatches event(s).
     * @param {?} event
     * @return {?}
     */
    function (event) {
        return this._internalStateOperations.getRootStateOperations().dispatch(event);
    };
    /**
     * @param {?} selector
     * @return {?}
     */
    Store.prototype.select = /**
     * @param {?} selector
     * @return {?}
     */
    function (selector) {
        /** @type {?} */
        var selectorFn = getSelectorFn(selector);
        return this._stateStream.pipe(map(selectorFn), catchError((/**
         * @param {?} err
         * @return {?}
         */
        function (err) {
            // if error is TypeError we swallow it to prevent usual errors with property access
            if (err instanceof TypeError) {
                return of(undefined);
            }
            // rethrow other errors
            throw err;
        })), distinctUntilChanged(), leaveNgxs(this._internalExecutionStrategy));
    };
    /**
     * @param {?} selector
     * @return {?}
     */
    Store.prototype.selectOnce = /**
     * @param {?} selector
     * @return {?}
     */
    function (selector) {
        return this.select(selector).pipe(take(1));
    };
    /**
     * @param {?} selector
     * @return {?}
     */
    Store.prototype.selectSnapshot = /**
     * @param {?} selector
     * @return {?}
     */
    function (selector) {
        /** @type {?} */
        var selectorFn = getSelectorFn(selector);
        return selectorFn(this._stateStream.getValue());
    };
    /**
     * Allow the user to subscribe to the root of the state
     */
    /**
     * Allow the user to subscribe to the root of the state
     * @param {?=} fn
     * @return {?}
     */
    Store.prototype.subscribe = /**
     * Allow the user to subscribe to the root of the state
     * @param {?=} fn
     * @return {?}
     */
    function (fn) {
        return this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy)).subscribe(fn);
    };
    /**
     * Return the raw value of the state.
     */
    /**
     * Return the raw value of the state.
     * @return {?}
     */
    Store.prototype.snapshot = /**
     * Return the raw value of the state.
     * @return {?}
     */
    function () {
        return this._internalStateOperations.getRootStateOperations().getState();
    };
    /**
     * Reset the state to a specific point in time. This method is useful
     * for plugin's who need to modify the state directly or unit testing.
     */
    /**
     * Reset the state to a specific point in time. This method is useful
     * for plugin's who need to modify the state directly or unit testing.
     * @param {?} state
     * @return {?}
     */
    Store.prototype.reset = /**
     * Reset the state to a specific point in time. This method is useful
     * for plugin's who need to modify the state directly or unit testing.
     * @param {?} state
     * @return {?}
     */
    function (state) {
        return this._internalStateOperations.getRootStateOperations().setState(state);
    };
    Store.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    Store.ctorParameters = function () { return [
        { type: StateStream },
        { type: InternalStateOperations },
        { type: NgxsConfig },
        { type: InternalNgxsExecutionStrategy }
    ]; };
    return Store;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Allows the select decorator to get access to the DI store.
 * @ignore
 */
var SelectFactory = /** @class */ (function () {
    function SelectFactory(store, config) {
        SelectFactory.store = store;
        SelectFactory.config = config;
    }
    SelectFactory.store = undefined;
    SelectFactory.config = undefined;
    SelectFactory.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    SelectFactory.ctorParameters = function () { return [
        { type: Store },
        { type: NgxsConfig }
    ]; };
    return SelectFactory;
}());
/**
 * Decorator for selecting a slice of state from the store.
 * @param {?=} selectorOrFeature
 * @param {...?} paths
 * @return {?}
 */
function Select(selectorOrFeature) {
    var paths = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        paths[_i - 1] = arguments[_i];
    }
    return (/**
     * @param {?} target
     * @param {?} name
     * @return {?}
     */
    function (target, name) {
        /** @type {?} */
        var selectorFnName = '__' + name + '__selector';
        if (!selectorOrFeature) {
            selectorOrFeature = removeDollarAtTheEnd(name);
        }
        /** @type {?} */
        var createSelect = (/**
         * @param {?} fn
         * @return {?}
         */
        function (fn) {
            /** @type {?} */
            var store = SelectFactory.store;
            if (!store) {
                throw new Error('SelectFactory not connected to store!');
            }
            return store.select(fn);
        });
        /** @type {?} */
        var createSelector = (/**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var config = SelectFactory.config;
            if (typeof selectorOrFeature === 'string') {
                /** @type {?} */
                var propsArray = paths.length
                    ? __spread([selectorOrFeature], paths) : selectorOrFeature.split('.');
                return propGetter(propsArray, (/** @type {?} */ (config)));
            }
            else if (selectorOrFeature[META_KEY] && selectorOrFeature[META_KEY].path) {
                return propGetter(selectorOrFeature[META_KEY].path.split('.'), (/** @type {?} */ (config)));
            }
            else {
                return selectorOrFeature;
            }
        });
        if (target[selectorFnName]) {
            throw new Error('You cannot use @Select decorator and a ' + selectorFnName + ' property.');
        }
        if (delete target[name]) {
            Object.defineProperty(target, selectorFnName, {
                writable: true,
                enumerable: false,
                configurable: true
            });
            Object.defineProperty(target, name, {
                get: (/**
                 * @return {?}
                 */
                function () {
                    return (this[selectorFnName] ||
                        (this[selectorFnName] = createSelect.apply(this, [createSelector()])));
                }),
                enumerable: true,
                configurable: true
            });
        }
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Init action
 */
var  /**
 * Init action
 */
InitState = /** @class */ (function () {
    function InitState() {
    }
    Object.defineProperty(InitState, "type", {
        get: /**
         * @return {?}
         */
        function () {
            // NOTE: Not necessary to declare the type in this way in your code. See https://github.com/ngxs/store/pull/644#issuecomment-436003138
            return '@@INIT';
        },
        enumerable: true,
        configurable: true
    });
    return InitState;
}());
/**
 * Update action
 */
var  /**
 * Update action
 */
UpdateState = /** @class */ (function () {
    function UpdateState() {
    }
    Object.defineProperty(UpdateState, "type", {
        get: /**
         * @return {?}
         */
        function () {
            // NOTE: Not necessary to declare the type in this way in your code. See https://github.com/ngxs/store/pull/644#issuecomment-436003138
            return '@@UPDATE_STATE';
        },
        enumerable: true,
        configurable: true
    });
    return UpdateState;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Root module
 * @ignore
 */
var NgxsRootModule = /** @class */ (function () {
    function NgxsRootModule(factory, internalStateOperations, store, select, states, lifecycleStateManager) {
        if (states === void 0) { states = []; }
        // add stores to the state graph and return their defaults
        /** @type {?} */
        var results = factory.addAndReturnDefaults(states);
        internalStateOperations.setStateToTheCurrentWithNew(results);
        // connect our actions stream
        factory.connectActionHandlers();
        // dispatch the init action and invoke init and bootstrap functions after
        lifecycleStateManager.ngxsBootstrap(new InitState(), results);
    }
    NgxsRootModule.decorators = [
        { type: NgModule }
    ];
    /** @nocollapse */
    NgxsRootModule.ctorParameters = function () { return [
        { type: StateFactory },
        { type: InternalStateOperations },
        { type: Store },
        { type: SelectFactory },
        { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [ROOT_STATE_TOKEN,] }] },
        { type: LifecycleStateManager }
    ]; };
    return NgxsRootModule;
}());
/**
 * Feature module
 * @ignore
 */
var NgxsFeatureModule = /** @class */ (function () {
    function NgxsFeatureModule(store, internalStateOperations, factory, states, lifecycleStateManager) {
        // Since FEATURE_STATE_TOKEN is a multi token, we need to
        // flatten it [[Feature1State, Feature2State], [Feature3State]]
        /** @type {?} */
        var flattenedStates = ((/** @type {?} */ ([]))).concat.apply(((/** @type {?} */ ([]))), __spread(states));
        // add stores to the state graph and return their defaults
        /** @type {?} */
        var results = factory.addAndReturnDefaults(flattenedStates);
        if (results.states.length) {
            internalStateOperations.setStateToTheCurrentWithNew(results);
            // dispatch the update action and invoke init and bootstrap functions after
            lifecycleStateManager.ngxsBootstrap(new UpdateState(), results);
        }
    }
    NgxsFeatureModule.decorators = [
        { type: NgModule, args: [{},] }
    ];
    /** @nocollapse */
    NgxsFeatureModule.ctorParameters = function () { return [
        { type: Store },
        { type: InternalStateOperations },
        { type: StateFactory },
        { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [FEATURE_STATE_TOKEN,] }] },
        { type: LifecycleStateManager }
    ]; };
    return NgxsFeatureModule;
}());
/**
 * @param {?} options
 * @return {?}
 */
function ngxsConfigFactory(options) {
    /** @type {?} */
    var config = Object.assign(new NgxsConfig(), options);
    return config;
}
/**
 * @param {?} bootstrapper
 * @return {?}
 */
function appBootstrapListenerFactory(bootstrapper) {
    return (/**
     * @return {?}
     */
    function () { return bootstrapper.bootstrap(); });
}
/** @type {?} */
var ROOT_OPTIONS = new InjectionToken('ROOT_OPTIONS');
/**
 * Ngxs Module
 */
var NgxsModule = /** @class */ (function () {
    function NgxsModule() {
    }
    /**
     * Root module factory
     */
    /**
     * Root module factory
     * @param {?=} states
     * @param {?=} options
     * @return {?}
     */
    NgxsModule.forRoot = /**
     * Root module factory
     * @param {?=} states
     * @param {?=} options
     * @return {?}
     */
    function (states, options) {
        if (states === void 0) { states = []; }
        if (options === void 0) { options = {}; }
        return {
            ngModule: NgxsRootModule,
            providers: __spread([
                StateFactory,
                StateContextFactory,
                Actions,
                InternalActions,
                NgxsBootstrapper,
                ConfigValidator,
                LifecycleStateManager,
                InternalDispatcher,
                InternalDispatchedActionResults,
                InternalStateOperations,
                InternalNgxsExecutionStrategy,
                Store,
                StateStream,
                SelectFactory,
                PluginManager
            ], states, [
                {
                    provide: NGXS_EXECUTION_STRATEGY,
                    useClass: options.executionStrategy || DispatchOutsideZoneNgxsExecutionStrategy
                },
                {
                    provide: ROOT_STATE_TOKEN,
                    useValue: states
                },
                {
                    provide: ROOT_OPTIONS,
                    useValue: options
                },
                {
                    provide: NgxsConfig,
                    useFactory: ngxsConfigFactory,
                    deps: [ROOT_OPTIONS]
                },
                {
                    provide: APP_BOOTSTRAP_LISTENER,
                    useFactory: appBootstrapListenerFactory,
                    multi: true,
                    deps: [NgxsBootstrapper]
                }
            ])
        };
    };
    /**
     * Feature module factory
     */
    /**
     * Feature module factory
     * @param {?=} states
     * @return {?}
     */
    NgxsModule.forFeature = /**
     * Feature module factory
     * @param {?=} states
     * @return {?}
     */
    function (states) {
        if (states === void 0) { states = []; }
        return {
            ngModule: NgxsFeatureModule,
            providers: __spread([
                StateFactory,
                PluginManager
            ], states, [
                {
                    provide: FEATURE_STATE_TOKEN,
                    multi: true,
                    useValue: states
                }
            ])
        };
    };
    NgxsModule.decorators = [
        { type: NgModule, args: [{},] }
    ];
    return NgxsModule;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Decorates a method with a action information.
 * @param {?} actions
 * @param {?=} options
 * @return {?}
 */
function Action(actions, options) {
    return (/**
     * @param {?} target
     * @param {?} name
     * @param {?} _descriptor
     * @return {?}
     */
    function (target, name, _descriptor) {
        var e_1, _a;
        /** @type {?} */
        var meta = ensureStoreMetadata(target.constructor);
        if (!Array.isArray(actions)) {
            actions = [actions];
        }
        try {
            for (var actions_1 = __values(actions), actions_1_1 = actions_1.next(); !actions_1_1.done; actions_1_1 = actions_1.next()) {
                var action = actions_1_1.value;
                /** @type {?} */
                var type = action.type;
                if (!meta.actions[type]) {
                    meta.actions[type] = [];
                }
                meta.actions[type].push({
                    fn: name,
                    options: options || {},
                    type: type
                });
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (actions_1_1 && !actions_1_1.done && (_a = actions_1.return)) _a.call(actions_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Decorates a class with ngxs state information.
 * @template T
 * @param {?} options
 * @return {?}
 */
function State(options) {
    /**
     * @param {?} inheritedStateClass
     * @return {?}
     */
    function getStateOptions(inheritedStateClass) {
        /** @type {?} */
        var inheritanceOptions = inheritedStateClass[META_OPTIONS_KEY] || {};
        return (/** @type {?} */ (__assign({}, inheritanceOptions, options)));
    }
    /**
     * @param {?} params
     * @return {?}
     */
    function mutateMetaData(params) {
        var meta = params.meta, inheritedStateClass = params.inheritedStateClass, optionsWithInheritance = params.optionsWithInheritance;
        var children = optionsWithInheritance.children, defaults = optionsWithInheritance.defaults, name = optionsWithInheritance.name;
        StoreValidators.checkCorrectStateName(name);
        if (inheritedStateClass.hasOwnProperty(META_KEY)) {
            /** @type {?} */
            var inheritedMeta = inheritedStateClass[META_KEY] || {};
            meta.actions = __assign({}, meta.actions, inheritedMeta.actions);
        }
        meta.children = children;
        meta.defaults = defaults;
        meta.name = name;
    }
    return (/**
     * @param {?} target
     * @return {?}
     */
    function (target) {
        /** @type {?} */
        var meta = ensureStoreMetadata(target);
        /** @type {?} */
        var inheritedStateClass = Object.getPrototypeOf(target);
        /** @type {?} */
        var optionsWithInheritance = getStateOptions(inheritedStateClass);
        mutateMetaData({ meta: meta, inheritedStateClass: inheritedStateClass, optionsWithInheritance: optionsWithInheritance });
        target[META_OPTIONS_KEY] = optionsWithInheritance;
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Decorator for memoizing a state selector.
 * @param {?=} selectors
 * @return {?}
 */
function Selector(selectors) {
    return (/**
     * @param {?} target
     * @param {?} methodName
     * @param {?} descriptor
     * @return {?}
     */
    function (target, methodName, descriptor) {
        if (descriptor.value !== null) {
            /** @type {?} */
            var originalFn = descriptor.value;
            /** @type {?} */
            var memoizedFn_1 = createSelector(selectors, originalFn.bind(target), { containerClass: target, selectorName: methodName });
            return {
                configurable: true,
                get: /**
                 * @return {?}
                 */
                function () {
                    return memoizedFn_1;
                }
            };
        }
        else {
            throw new Error('Selectors only work on methods');
        }
    });
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var NoopNgxsExecutionStrategy = /** @class */ (function () {
    function NoopNgxsExecutionStrategy() {
    }
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    NoopNgxsExecutionStrategy.prototype.enter = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        return func();
    };
    /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    NoopNgxsExecutionStrategy.prototype.leave = /**
     * @template T
     * @param {?} func
     * @return {?}
     */
    function (func) {
        return func();
    };
    NoopNgxsExecutionStrategy.decorators = [
        { type: Injectable }
    ];
    return NoopNgxsExecutionStrategy;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { NgxsModule, Action, Store, State, Select, Actions, getSelectorMetadata, getStoreMetadata, ensureStoreMetadata, ensureSelectorMetadata, ofAction, ofActionDispatched, ofActionSuccessful, ofActionCanceled, ofActionErrored, ofActionCompleted, Selector, getActionTypeFromInstance, actionMatcher, createSelector, NoopNgxsExecutionStrategy, NGXS_PLUGINS, StateStream, setValue, getValue, InitState, UpdateState, InternalActions as ɵh, OrderedSubject as ɵg, SelectFactory as ɵf, DispatchOutsideZoneNgxsExecutionStrategy as ɵx, InternalNgxsExecutionStrategy as ɵu, NGXS_EXECUTION_STRATEGY as ɵn, ConfigValidator as ɵv, InternalDispatchedActionResults as ɵp, InternalDispatcher as ɵq, LifecycleStateManager as ɵw, StateContextFactory as ɵr, StateFactory as ɵo, InternalStateOperations as ɵs, NgxsFeatureModule as ɵb, NgxsRootModule as ɵa, ROOT_OPTIONS as ɵe, appBootstrapListenerFactory as ɵd, ngxsConfigFactory as ɵc, PluginManager as ɵt, FEATURE_STATE_TOKEN as ɵk, NgxsConfig as ɵm, ROOT_STATE_TOKEN as ɵj, SELECTOR_META_KEY as ɵl };

//# sourceMappingURL=ngxs-store.js.map