import * as c from "@ts-std/codec";
export declare type Dict<T> = {
    [key: string]: T;
};
export declare function tuple<L extends any[]>(...items: L): L;
export declare function exec<T>(fn: () => T): T;
export declare function setExtend<T, U>(a: Set<T>, b: U[]): Set<T | U>;
export declare type UnionKeys<T> = T extends T ? keyof T : never;
export declare type OmitVariants<U, K extends UnionKeys<U>, V extends U[K]> = U extends U ? U[K] extends V ? never : U : never;
export declare type PickVariants<U, K extends UnionKeys<U>, V extends U[K]> = U extends U ? U[K] extends V ? U : never : never;
export declare type UnboxArray<A extends unknown[]> = A extends (infer T)[] ? T : never;
export declare class Registry<T> {
    protected items: Dict<T>;
    peek(key: string): boolean;
    take(key: string): T | undefined;
    put(key: string, item: T): void;
}
export declare class Cache<T> {
    protected map: Map<string, T>;
    has(key: string): boolean;
    get(key: string): T | undefined;
    set(key: string, value: T): T;
}
export declare function cachedLookup<T>(fn: (key: string) => T): (key: string) => T;
export declare type NonEmpty<T> = [
    T,
    ...T[]
];
export declare namespace NonEmpty {
    function decoder<T>(decoder: c.Decoder<T>): c.Decoder<NonEmpty<T>>;
    function flattenInto<T>(item: T | NonEmpty<T>): NonEmpty<T>;
}
export declare type NonEmptyOrSingle<T> = T | NonEmpty<T>;
export declare namespace NonEmptyOrSingle {
    function decoder<T>(decoder: c.Decoder<T>): c.Decoder<NonEmptyOrSingle<T>>;
}
export declare function longestMatchingStem(value: string, stems: string[]): string | undefined;
