import { Observable } from 'rxjs';
import { StorageType } from '../constants/persistence.storage_type';
import { PersistenceConfig } from '../types/persistence.config';
import { ItemDefinition } from '../types/persistence.item_definition';
import { CacheConfig } from '../types/persistence.cache_config';
import { IPersistenceContainer } from '../abstracts/persistence.container';
import { ICache } from '../abstracts/persistence.cache';
/**
 * Service used to persist application wide storage.  Iterms may be obtained from the Service
 * itself or used through proxies.  This framework also supports an immutable flag which will
 * instruct the service that the objects stored within should not have any side-effects when
 * objects on the outside are changed.
 *
 * Note on immutability: Only clonable objects will be saved when the immutable flag is
 * set.  This framework will do a deep clone of the objects in question, but items such
 * as functions will not be preserved.  Also, immutability is slower.  If you have objects
 * that are well controlled with a single component, it is suggested that you don't save your
 * item as immutable.
 *
 * @export
 * @class PersistenceService
 *
 * @author Scott O'Bryan
 * @since 1.0
 */
export declare class PersistenceService {
    private _emitter;
    private _storage;
    /**
     * Returns a hot observable that can be used to monitor changes to this framework over
     * time.  Subscribing to this observable has the potential of causing memory leaks,
     * so each subscriber is expected to unsubscribe when notifications are no longer
     * needed.
     *
     * @param {ItemDefinition} [config] the config object that can be used to filter the
     *                                  results.  If not provided, all changes will be
     *                                  returned.
     *
     * @returns {Observable<ItemDefinition>} a hot observable that can monitor changes
     *                                  to this framework over time.
     */
    changes(config?: ItemDefinition): Observable<ItemDefinition>;
    /**
     * Returns an object from storage.  If the object was stored with the immutable flag
     * set, then the object returned will not have any side-effects into the stored model
     * until it is set again.
     *
     * @param {string} key a string represnting the stored value
     * @param {StorageType} [type=StorageType.MEMORY] the storage type
     * @returns {*} the value or undefined if the object is not set
     */
    get(key: string, type?: StorageType): any;
    /**
     * Puts an object into storage, replacing any item that may be in there.  By default,
     * the object is stored as-is, which means that when other areas of code get the
     * object, they can mutate it.
     *
     * As immutable storage is slower, and the reconstituted logic may be
     * missing functions or metadata, it is recommended to use this only
     * if you need to ensure the integrity of the stored object on each set
     * as might be the case if you make use of the "change" emitter.
     *
     * @param {string} key the key that will represent the value
     * @param {*} value the value to store
     * @param {PersistenceConfig} [config={}] any additional configuration
     * @returns {boolean} which is <code>true</code> if the value was stored successfully
     */
    set(key: string, value: any, config?: PersistenceConfig): boolean;
    /**
     * Clears a value stored in the service for the given type.
     *
     * @param {string} key  the key of the stored value
     * @param {StorageType} [type=StorageType.MEMORY] the type of storage used
     * @returns {*} the item that was removed (if any)
     */
    remove(key: string, type?: StorageType): any;
    /**
     * Clears all stored items for a particular storage type.
     *
     * @param {StorageType} [type=StorageType.MEMORY] the type of storage to clear
     */
    removeAll(type?: StorageType): void;
    /**
     * Cleans up any expired objects in the cache.
     *
     * @param {StorageType} [type=StorageType.MEMORY] the type of storage to clean
     */
    clean(type?: StorageType): void;
    /**
     * Create a property on the object that is bound to this stored value.  This method
     * requires ES5 compatibility and the property will have special rules associated
     * with it.  The name of the property will be "key", and the value stored in the
     * configured storage will be prefix + key.
     *
     * @template T the type of property
     * @param {*} obj the object where the property will be bound to
     * @param {string} propName the name of the property to be bound
     * @param {string} key the key used for the storage of the item
     * @param {PersistenceConfig} [config={}] any additional configuration
     */
    defineProperty<T>(obj: any, propName: string, key: string, config?: PersistenceConfig): void;
    /**
     * Returns a facade that makes things a bit easier when interacting with the service.
     * The facade will use the prefix in order to isolate they keystore.  If no prefix is
     * defined, the keystore will be mapped as usual with the keys working as-is in the
     * storage.
     *
     * @param config the config for the facade
     * @param prefix the prefix to use for isolation of the storage
     *
     * @return a PersistenceFacade object representing this store
     */
    createContainer(namespace: string, config?: PersistenceConfig): IPersistenceContainer;
    /**
     * Returns a cache proxy that makes interacting with this service a little bit easier.  The
     * proxy returned will have a set key, a generic loader, and a consistent set of config
     * parameters. Please note that the "expires" property of the config might have unforseen
     * side-effects to the cache in that if the expires setting is already passed, the cache will
     * no longer cache values until a new proxy is created.
     *
     * @param key    they key for the item in the persistence layer
     * @param loader the function to load the intiial value.  Must return either a value or
     *               an Observable of that value.  If an observable is returned, it will be
     *               converted into a single by this method and returned to the subscriber.
     * @param config optional config object used to "set" the value if it has not already
     *               been loaded.  If a "type" is not specified, memory storage will be
     *               used.
     *
     * @returns a CacheProxy that can be used to interact with this cache.
     */
    createCache<T>(key: string, loader: () => T | Observable<T>, config?: CacheConfig): ICache<T>;
    private _getStorage(type);
    private _calculateExpires(maxAge);
}
