/**
 * type `CacheOptions`
 */
export interface CacheOptions {
    /**
     * (optional) cache backend type (default: 'redis')
     */
    type?: 'memcached' | 'redis';
    /**
     * (optional) cache server endpoint (not required for dummy-cache)
     */
    endpoint?: string;
    /**
     * (optional) namespace. used as cache key prefix to avoid key collision between different services
     */
    ns?: string;
    /**
     * (optional) default timeout of cache entries. 0 for unlimited (default: 1-day)
     */
    defTimeout?: number;
}
/**
 * type `CacheKey`
 */
export declare type CacheKey = string | number;
/**
 * type: `Timeout`
 */
export interface Timeout {
    /**
     * key will be expired after given number of seconds
     */
    expireIn?: number;
    /**
     * key will be expired in given Unix timestamp (seconds since epoch)
     *  - ignored if 'expireIn' is provided
     *  - not accurate because this value is replaced to time to live in seconds using Math.ceil()
     */
    expireAt?: number;
}
/**
 * type `CacheEntry`: parameter type of 'setMulti' operation
 */
export interface CacheEntry<CacheValue> {
    /**
     * key
     */
    key: CacheKey;
    /**
     * value
     */
    val: CacheValue;
    /**
     * timeout - same effect as 'expireIn' if given value is number
     */
    timeout?: number | Timeout;
}
/**
 * type `KeyValueMap`: result type of 'getMulti' operation
 */
export declare type KeyValueMap<CacheValue> = Record<CacheKey, CacheValue>;
/**
 * class: `CacheKeyMakable`
 * - to provide the custom key-string of cache.
 * - the global pkey would be like `<project>:<model.ns>:<model.type>::<cache-key>` (ex: `lemon:SS:item::100001`)
 */
export interface CacheKeyMakable {
    /**
     * make the global pkey
     * - default must be like `${ns}${delim}${key}`
     */
    (ns: string, delim: string, key: CacheKey): string;
}
/**
 * class: `CacheSupportable`
 * - support basic cache operation(read/write/timeout).
 */
export interface CacheSupportable<CacheValue = any> {
    /**
     * save into cache w/ timeout(sec)
     */
    set(key: CacheKey, val: CacheValue, timeout?: number | Timeout): Promise<boolean>;
    /**
     * read from cache
     */
    get(key: CacheKey): Promise<CacheValue>;
    /**
     * increment number by `inc`
     * - should be atomic operation w/ thread safe.
     */
    inc(key: CacheKey, inc: number): Promise<number>;
}
/**
 * class `CacheService`
 * - common service to provide cache
 */
export declare class CacheService<CacheValue = any> implements CacheSupportable<CacheValue> {
    /**
     * Environment variable name for cache server endpoint
     * @static
     */
    static readonly ENV_CACHE_ENDPOINT = "CACHE_ENDPOINT";
    /**
     * Environment variable name for default cache timeout
     * @static
     */
    static readonly ENV_CACHE_DEFAULT_TIMEOUT = "CACHE_DEFAULT_TIMEOUT";
    /**
     * Default cache timeout
     * @static
     */
    static readonly DEF_CACHE_DEFAULT_TIMEOUT: number;
    /**
     * Namespace delimiter
     * @private
     * @static
     */
    private static readonly NAMESPACE_DELIMITER;
    /**
     * Namespace of cache key
     */
    readonly ns: string;
    /**
     * the final options to create this service.
     */
    readonly options: CacheOptions;
    /**
     * maker of cache-key
     */
    readonly maker: CacheKeyMakable;
    /**
     * Cache backend instance
     * @private
     */
    private readonly backend;
    /**
     * Factory method
     *
     * @param options   (optional) cache options
     * @param maker     (optional) custome cache-pkey generator.
     * @static
     */
    static create(options?: CacheOptions, maker?: CacheKeyMakable): CacheService;
    /**
     * Protected constructor -> use CacheService.create()
     * WARN! - do not create directly.˜
     *
     * @param backend  cache backend object
     * @param params   params to create service.
     * @protected
     */
    protected constructor(backend: CacheBackend, params?: {
        /** (optional) namespace of cache key (default: '') */
        ns?: string;
        /** (optional) the final options to create() */
        options?: CacheOptions;
        /** custom key-maker */
        maker?: CacheKeyMakable;
    });
    /**
     * Say hello
     */
    hello(): string;
    /**
     * for convient, make another typed service.
     * - it add `type` into key automatically.
     *
     * @param type model-type like 'test'
     * @param delimiter (optional) delim bewteen type and key (default ':')
     * @returns the typed CacheService
     */
    cloneByType(type: string, delimiter?: string): CacheService<any>;
    /**
     * Close backend and connection
     */
    close(): Promise<void>;
    /**
     * Check whether the key is cached
     *
     * @return  true if the key is cached
     */
    exists(key: CacheKey): Promise<boolean>;
    /**
     * List all keys
     *
     * @return  list of keys
     */
    keys(): Promise<string[]>;
    /**
     * Store a key
     *
     * @param key
     * @param val
     * @param timeout   (optional) TTL in seconds or Timeout object
     * @return  true on success
     */
    set(key: CacheKey, val: CacheValue, timeout?: number | Timeout): Promise<boolean>;
    /**
     * Store multiple keys
     *
     * @param entries
     * @return  true on success
     */
    setMulti(entries: CacheEntry<CacheValue>[]): Promise<boolean>;
    /**
     * Retrieve a key
     *
     * @param key
     */
    get(key: CacheKey): Promise<CacheValue | undefined>;
    /**
     * Get multiple keys
     *
     * @param keys
     */
    getMulti(keys: CacheKey[]): Promise<KeyValueMap<CacheValue>>;
    /**
     * Increment the integer value of a key
     *
     * @param key
     * @param inc   number to increment
     */
    increment(key: CacheKey, inc: number): Promise<number>;
    /**
     * same as increment()
     */
    inc(key: CacheKey, inc: number): Promise<number>;
    /**
     * Set the value of a key and return its old value
     */
    getAndSet(key: CacheKey, val: CacheValue): Promise<CacheValue | undefined>;
    /**
     * Get and delete the key
     *
     * @param key
     */
    getAndDelete(key: CacheKey): Promise<CacheValue | undefined>;
    /**
     * Delete a key
     *
     * @param key
     * @return  true on success
     */
    delete(key: CacheKey): Promise<boolean>;
    /**
     * Delete multiple keys
     *
     * @param keys
     * @return  number of deleted entries
     */
    deleteMulti(keys: CacheKey[]): Promise<boolean[]>;
    /**
     * Set or update the timeout of a key
     *
     * @param key
     * @param timeout   TTL in seconds or Timeout object
     * @return  true on success
     */
    setTimeout(key: CacheKey, timeout: number | Timeout): Promise<boolean>;
    /**
     * Get remaining time to live in milliseconds
     *
     * @return
     *  - number of milliseconds to expire
     *  - undefined if the key does not exist
     *  - 0 if the key has no timeout
     */
    getTimeout(key: CacheKey): Promise<number | undefined>;
    /**
     * Remove the timeout from a key
     *
     * @param key
     */
    removeTimeout(key: CacheKey): Promise<boolean>;
    /**
     * Get namespace prefixed cache key
     *
     * @param key
     * @protected
     */
    asNamespacedKey(key: CacheKey): string;
}
/**
 * class `DummyCacheService`: use 'node-cache' library
 */
export declare class DummyCacheService extends CacheService {
    /**
     * Singleton node-cache backend
     *
     * @private
     * @static
     */
    private static backend;
    /**
     * Factory method
     *
     * @param options   (optional) cache options
     * @static
     */
    static create(options?: CacheOptions): DummyCacheService;
    /**
     * Say hello
     */
    hello(): string;
}
/**
 * function `sleep`
 * @param ms    duration in milliseconds
 */
export declare function sleep(ms: number): Promise<void>;
/**
 * Get TTL from timeout
 * @param timeout   timeout in seconds or Timeout object
 * @return  remaining time to live in seconds
 */
export declare function toTTL(timeout: number | Timeout): number;
/**
 * Get timestamp of expiration from TTL
 * @param ttl   remaining time to live in seconds
 * @return      timestamp in milliseconds since epoch
 */
export declare function fromTTL(ttl: number): number;
/** ********************************************************************************************************************
 *  Internal Types
 ** ********************************************************************************************************************/
/**
 * type `ItemEntry`: parameter for mset operation
 */
interface ItemEntry<T = any> {
    key: string;
    val: T;
    ttl?: number;
}
/**
 * interface `CacheBackend`
 * @internal
 */
interface CacheBackend {
    /**
     * backend type
     */
    readonly name: string;
    /**
     * Set the value of a key
     *
     * @param key
     * @param val
     * @param ttl   (optional) time to live in seconds
     * @return  true on success
     */
    set<T>(key: string, val: T, ttl?: number): Promise<boolean>;
    /**
     * Get the value of a key
     *
     * @param key
     * @return  the value of key, or undefined when key does not exist
     */
    get<T>(key: string): Promise<T | undefined>;
    /**
     * Set multiple keys to multiple values
     *
     * @param entries   see ItemEntry
     * @return  true on success
     */
    mset<T>(entries: ItemEntry<T>[]): Promise<boolean>;
    /**
     * Get the values of all the given keys
     *
     * @param keys
     * @return  key-value map
     */
    mget<T>(keys: string[]): Promise<{
        [key: string]: T;
    }>;
    /**
     * (optional) Set the value of a key and return its old value
     *
     * @param key
     * @param val
     * @return  the old value stored at key, or undefined when key did not exist
     */
    getset?<T, U>(key: string, val: T): Promise<U | undefined>;
    /**
     * (optional) Get the value of a key and remove the key
     *
     * @param key
     * @return  the old value stored at key, or undefined when key did not exist
     */
    pop?<T>(key: string): Promise<T | undefined>;
    /**
     * Increment the integer value of a key
     *
     * @param key
     * @param increment amount to increment
     * @return  the value of key after the increment
     */
    incr(key: string, increment: number): Promise<number>;
    /**
     * List all keys
     *
     * @return  list of keys
     */
    keys(): Promise<string[]>;
    /**
     * Determine if a key exists
     *
     * @param key
     * @return  true on success
     */
    has(key: string): Promise<boolean>;
    /**
     * Delete a key
     *
     * @param key
     * @return  true on success
     */
    del(key: string): Promise<boolean>;
    /**
     * Set the time to live in seconds
     *
     * @param key
     * @param ttl   time to live in seconds
     * @return  true on success
     */
    expire(key: string, ttl: number): Promise<boolean>;
    /**
     * Get the time to live for a key in milliseconds
     *
     * @param key
     * @return  the remaining time to live in milliseconds
     *          - 0 if the key exists but has no associated timeout
     *          - undefined if the key does not exist
     */
    ttl(key: string): Promise<number | undefined>;
    /**
     * Close connection(s) to the cache server
     */
    close(): Promise<void>;
}
export {};
