import Reference, { PathReference } from './reference';
import { Opaque, Slice, LinkedListNode } from '@glimmer/util';
export interface EntityTag<T> extends Reference<T> {
    value(): T;
    validate(snapshot: T): boolean;
}
export interface Tagged<T> {
    tag: EntityTag<T>;
}
export declare type Revision = number;
export declare const CONSTANT: Revision;
export declare const INITIAL: Revision;
export declare const VOLATILE: Revision;
export declare abstract class RevisionTag implements EntityTag<Revision> {
    abstract value(): Revision;
    validate(snapshot: Revision): boolean;
}
export declare class DirtyableTag extends RevisionTag {
    private revision;
    constructor(revision?: number);
    value(): Revision;
    dirty(): void;
}
export declare function combineTagged(tagged: ReadonlyArray<Tagged<Revision>>): RevisionTag;
export declare function combineSlice(slice: Slice<Tagged<Revision> & LinkedListNode>): RevisionTag;
export declare function combine(tags: RevisionTag[]): RevisionTag;
export declare abstract class CachedTag extends RevisionTag {
    private lastChecked;
    private lastValue;
    value(): Revision;
    protected invalidate(): void;
    protected abstract compute(): Revision;
}
export declare class UpdatableTag extends CachedTag {
    private tag;
    private lastUpdated;
    constructor(tag: RevisionTag);
    protected compute(): Revision;
    update(tag: RevisionTag): void;
}
export declare const CONSTANT_TAG: RevisionTag;
export declare const VOLATILE_TAG: RevisionTag;
export declare const CURRENT_TAG: DirtyableTag;
export interface VersionedReference<T> extends Reference<T>, Tagged<Revision> {
}
export interface VersionedPathReference<T> extends PathReference<T>, Tagged<Revision> {
    get(property: string): VersionedPathReference<Opaque>;
}
export declare abstract class CachedReference<T> implements VersionedReference<T> {
    abstract tag: RevisionTag;
    private lastRevision;
    private lastValue;
    value(): T;
    protected abstract compute(): T;
    protected invalidate(): void;
}
export declare type Mapper<T, U> = (value: T) => U;
export declare function map<T, U>(reference: VersionedReference<T>, mapper: Mapper<T, U>): VersionedReference<U>;
export declare class ReferenceCache<T> implements Tagged<Revision> {
    tag: RevisionTag;
    private reference;
    private lastValue;
    private lastRevision;
    private initialized;
    constructor(reference: VersionedReference<T>);
    peek(): T;
    revalidate(): Validation<T>;
    private initialize();
}
export declare type Validation<T> = T | NotModified;
export declare type NotModified = "adb3b78e-3d22-4e4b-877a-6317c2c5c145";
export declare function isModified<T>(value: Validation<T>): value is T;
