import { Eq } from 'fp-ts/Eq';
import * as A from './Adapter';
import * as D from './Disposable';
import * as E from './Env';
import * as O from './Option';
import * as RS from './ReaderStream';
/**
 * @since 0.11.0
 * @category Model
 */
export interface KV<K, E, A> extends Eq<A> {
    readonly key: K;
    readonly initial: E.Env<E, A>;
}
/**
 * @since 0.11.0
 * @category Model
 */
export interface Of<K, A> extends KV<K, unknown, A> {
}
/**
 * @since 0.11.0
 * @category Type-level
 */
export declare type KeyOf<A> = [A] extends [KV<infer R, any, any>] ? R : never;
/**
 * @since 0.11.0
 * @category Type-level
 */
export declare type EnvOf<A> = [A] extends [KV<any, infer R, any>] ? R : never;
/**
 * @since 0.11.0
 * @category Type-level
 */
export declare type ValueOf<A> = [A] extends [KV<any, any, infer R>] ? R : never;
/**
 * @since 0.11.0
 * @category Options
 */
export declare type Options<K, A> = {
    readonly key?: K;
} & Partial<Eq<A>>;
/**
 * Note that by default an incrementing index is utilized to generate a key if one is not
 * provided. In other words, by default, this is not referentially transparent for
 * your own convenience
 *
 * @since 0.11.0
 * @category Constructor
 */
export declare function make<E, A, K = symbol>(initial: E.Env<E, A>, options?: Options<K, A>): KV<K, E, A>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const get: <K, E, A>(kv: KV<K, E, A>) => E.Env<E & Get, A>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Get {
    readonly getKV: <K, E, A>(kv: KV<K, E, A>) => E.Env<E, A>;
}
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const has: <K, E, A>(kv: KV<K, E, A>) => E.Env<Has, boolean>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Has {
    readonly hasKV: <K, E, A>(kv: KV<K, E, A>) => E.Of<boolean>;
}
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const set: <K, E, A>(kv: KV<K, E, A>) => (value: A) => E.Env<E & Set, A>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Set {
    readonly setKV: <K, E, A>(kv: KV<K, E, A>, value: A) => E.Env<E, A>;
}
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const update: <K, E1, A>(kv: KV<K, E1, A>) => <E2>(f: (value: A) => E.Env<E2, A>) => E.Env<E1 & Set & E2 & Get, A>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const remove: <K, E, A>(kv: KV<K, E, A>) => E.Env<E & Remove, O.Option<A>>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Remove {
    readonly removeKV: <K, E, A>(kv: KV<K, E, A>) => E.Env<E, O.Option<A>>;
}
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Events {
    readonly kvEvents: Adapter;
}
/**
 * @since 0.12.0
 * @category Combinator
 */
export declare const getAdapter: E.Env<Events, readonly [(event: Event<any, any>) => void, import("@most/types").Stream<Event<any, any>>]>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const getSendEvent: E.Env<Events, (event: Event<any, any>) => void>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const sendEvent: <K, A>(event: Event<K, A>) => E.Env<Events, void>;
/**
 * @since 0.12.0
 * @category Combinator
 */
export declare const getKVEvents: RS.ReaderStream<Events, Event<any, any>>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const listenTo: <K, E, A>(kv: KV<K, E, A>) => RS.ReaderStream<Events, Event<K, A>>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const listenToValues: <K, E, A>(kv: KV<K, E, A>) => RS.ReaderStream<E & Events, O.Option<A>>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface ParentEnv {
    readonly parentKVEnv: O.Option<Env>;
}
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const getParentEnv: E.Env<ParentEnv, O.Option<Env>>;
/**
 * Traverse up the tree of KVEnv and parent KVEnv to find the closest KVEnv that
 * has reference for a given KV. This is useful for providing a React-like Context
 * API atop of KV.
 * @since 0.11.0
 * @category Combinator
 */
export declare const findKVProvider: <K, E, A>(ref: KV<K, E, A>) => E.Env<Env, Env>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const withProvider: <K, E, A>(kv: KV<K, E, A>) => <E2, B>(env: E.Env<E2, B>) => E.Env<E2 & Env, B>;
/**
 * @since 0.11.0
 * @category Combinator
 */
export declare const withProviderStream: <K, E, A>(kv: KV<K, E, A>) => <E2, B>(rs: RS.ReaderStream<E2, B>) => RS.ReaderStream<E2 & Env, B>;
/**
 * @since 0.12.0
 * @category Environment
 */
export interface Env extends Get, Has, Set, Remove, Events, ParentEnv {
}
/**
 * @since 0.12.0
 * @category Combinator
 */
export declare const getEnv: E.Env<Env, Env>;
/**
 * @since 0.11.0
 * @category Model
 */
export declare type Adapter = A.Adapter<Event<any, any>>;
/**
 * @since 0.12.0
 * @category Model
 */
export declare type Event<K, A> = Created<K, A> | Updated<K, A> | Removed<K>;
/**
 * @since 0.12.0
 * @category Model
 */
export interface Created<K, A> {
    readonly _tag: 'Created';
    readonly key: K;
    readonly value: A;
    readonly fromAncestor: boolean;
}
/**
 * @since 0.11.0
 * @category Refinement
 */
export declare const isCreated: <K, A>(event: Event<K, A>) => event is Created<K, A>;
/**
 * @since 0.12.0
 * @category Model
 */
export interface Updated<K, A> {
    readonly _tag: 'Updated';
    readonly key: K;
    readonly previousValue: A;
    readonly value: A;
    readonly fromAncestor: boolean;
}
/**
 * @since 0.11.0
 * @category Refinement
 */
export declare const isUpdated: <K, A>(event: Event<K, A>) => event is Updated<K, A>;
/**
 * @since 0.12.0
 * @category Model
 */
export interface Removed<K> {
    readonly _tag: 'Removed';
    readonly key: K;
    readonly fromAncestor: boolean;
}
/**
 * @since 0.11.0
 * @category Refinement
 */
export declare const isRemoved: <K, A>(event: Event<K, A>) => event is Removed<K>;
/**
 * @since 0.12.0
 * @category Deconstructor
 */
export declare const matchW: <A, K, B, C, D>(onCreated: (value: A, key: K) => B, onUpdated: (previousValue: A, value: A, key: K) => C, onDeleted: (key: K) => D) => (event: Event<K, A>) => B | C | D;
/**
 * @since 0.12.0
 * @category Deconstructor
 */
export declare const match: <A, K, B>(onCreated: (value: A, key: K) => B, onUpdated: (previousValue: A, value: A, key: K) => B, onDeleted: (key: K) => B) => (event: Event<K, A>) => B;
/**
 * @since 0.12.0
 * @category Environment Constructor
 */
export declare function env(options?: EnvOptions): Env;
/**
 * @since 0.11.0
 * @category Options
 */
export declare type EnvOptions = {
    readonly initial?: Iterable<readonly [any, any]>;
    readonly kvEvents?: Adapter;
    readonly parentEnv?: Env;
};
/**
 * Sample an Env with the latest references when updates have occured.
 * @since 0.11.0
 * @category Combinator
 */
export declare const sample: <E, A>(env: E.Env<E, A>) => RS.ReaderStream<E & Env, A>;
/**
 * A shared KV for keeping track of a context's disposable resources.
 * @since 0.11.0
 * @category KV
 */
export declare const Disposable: KV<symbol, unknown, D.SettableDisposable>;
/**
 * @since 0.11.0
 * @category Use
 */
export declare const useKeyedEnvs: <A>(Eq: Eq<A>) => E.Env<Env, {
    readonly findRefs: (key: A) => E.Env<Get, Env>;
    readonly deleteRefs: (key: A) => D.Disposable;
}>;
//# sourceMappingURL=KV.d.ts.map