import * as interfaces from "@starbeam/interfaces";
import { DescriptionArgs, DescriptionDetails, ReactiveId, CompositeInternals, Diff, Frame, MutableInternals, ReactiveInternals, ReactiveProtocol, Timestamp } from "@starbeam/interfaces";
import { Stack as StackProtocol } from "@starbeam/interfaces";
import { Stack as Stack$0 } from "@starbeam/interfaces";
import { CustomInspectFunction, InspectOptionsStylized, Style } from "util";
/// <reference types="node" />
import { UnknownFn } from "@starbeam/core-utils";
/**
 * This symbol is used in APIs that accept an ID to indicate that an existing ID should be reused.
 * This value should never be used as an ID.
 */
declare const REUSE_ID: unique symbol;
type REUSE_ID = typeof REUSE_ID;
interface DescriptionStatics {
    is: (description: unknown) => description is interfaces.Description;
    from: (args: interfaces.DescriptionArgs) => interfaces.Description;
}
type Description = interfaces.Description;
declare const Description: DescriptionStatics;
type JSONValue = string | number | boolean | null | JSONValue[] | {
    [key: string]: JSONValue;
};
interface DisplayStructOptions {
    readonly description: JSONValue;
}
type Fields = Record<PropertyKey, unknown>;
declare function DisplayStruct(name: string, fields: Record<PropertyKey, unknown>, options?: DisplayStructOptions): object;
declare const INSPECT: unique symbol;
declare const DEBUG: unique symbol;
type DEBUG = typeof DEBUG;
declare const DEBUG_NAME: unique symbol;
type DEBUG_NAME = typeof DEBUG_NAME;
/**
 * The TS type for CustomInspectFunction is wrong. You're allowed to return an
 * object, which then gets inspected, but TS assumes you have to return a
 * string.
 */
type InspectFunction = (...args: Parameters<CustomInspectFunction>) => unknown;
interface Inspect {
    [INSPECT]: InspectFunction;
}
declare class Debug {
    #private;
    static create(name: string, options: InspectOptionsStylized): Debug;
    private constructor();
    stylize(text: string, styleType: Style): string;
    struct(fields: Fields, options?: DisplayStructOptions): object;
}
interface DebugClass<I> {
    name: string;
    prototype: I & Partial<Inspect>;
}
declare function inspector<I>(Class: DebugClass<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
I extends {
    [INSPECT]: any;
} ? `Do not pass a class to debug() that already implements nodejs.util.inspect.custom` : I>, name?: string): {
    define: (inspector: (instance: I, debug: Debug) => unknown) => void;
};
declare function inspect(value: unknown, ...args: Parameters<CustomInspectFunction>): unknown;
type LoggedFunction = <T>(value: T, log?: (value: T) => void) => T;
declare const logged: LoggedFunction;
declare enum LogLevel {
    Trace = 0,
    Debug = 1,
    Info = 2,
    Warn = 3,
    Error = 4,
    Fatal = 5
}
declare class LoggerAsLevel {
    #private;
    constructor(logger: Logger, level: LogLevel, config: LoggerConfig);
    log: (arg: unknown, ...args: unknown[]) => void;
    get withStack(): LoggerWithStack;
}
declare class LoggerWithStack {
    #private;
    constructor(logger: Logger, level: LogLevel, config: LoggerConfig);
    log(arg: unknown, ...args: unknown[]): void;
}
interface LoggerConfig {
    readonly minimum: LogLevel;
}
declare class Logger {
    #private;
    readonly trace: LoggerAsLevel;
    readonly debug: LoggerAsLevel;
    readonly info: LoggerAsLevel;
    readonly warn: LoggerAsLevel;
    readonly error: LoggerAsLevel;
    readonly fatal: LoggerAsLevel;
    constructor(console: Console, config: LoggerConfig);
    set level(level: LogLevel);
    get isVerbose(): boolean;
    get isDebug(): boolean;
    configure(config: Partial<LoggerConfig>): void;
    send(level: LogLevel, { args, stack }: {
        args: unknown[];
        stack?: boolean;
    }): void;
}
declare const LOGGER: Logger;
declare class Style$0 {
    #private;
    static create(property: string, value: string): Style$0;
    constructor(property: string, value: string);
    toCSS(): string;
}
declare class Styles {
    #private;
    add(property: string, value: string): void;
    toCSS(): string;
}
declare class Fragment {
    #private;
    constructor(content: string);
    css(style: `${string}:${string}`): this;
    append(buffer: Buffer): void;
}
declare function Styled(content: string): Fragment;
type IntoFragment = string | [
    content: string,
    ...styles: `${string}:${string}`[]
];
type IntoBlock = IntoFragment[] | "";
declare class Block {
    #private;
    add(fragment: Fragment | string): void;
    appendTo(buffer: Buffer): void;
}
declare function Message(into: IntoBlock[], options?: {
    plain: boolean;
}): unknown[];
declare class Buffer {
    #private;
    static styled(): Buffer;
    static plain(): Buffer;
    constructor(plain: boolean);
    add(content: string, style?: string): void;
    message(): unknown[];
    break(): void;
}
declare function describeModule(module: string): DescribedModule;
interface DisplayRoot {
    name?: string;
    prefix: string;
}
declare class DisplayPathParts {
    #private;
    constructor({ path, root }: {
        path: string;
        root?: DisplayRoot;
    });
    finish(options?: {
        action?: string;
        loc?: Loc;
    }): DisplayParts;
}
declare class DisplayParts implements interfaces.DisplayParts {
    #private;
    constructor({ path, root, action, loc }: {
        path: string;
        root?: DisplayRoot | undefined;
        action?: string | undefined;
        loc?: Loc | undefined;
    });
    get action(): string | undefined;
    get loc(): Loc | undefined;
    get path(): string;
    get root(): DisplayRoot | undefined;
    display(): string;
}
declare class DescribedModule {
    #private;
    constructor(module: DescribedModulePath | DescribedPackage);
    display(location?: {
        loc?: Loc | undefined;
        action?: string | undefined;
    }, options?: interfaces.StackFrameDisplayOptions): string;
    parts(location?: {
        loc?: Loc | undefined;
        action?: string | undefined;
    }, options?: interfaces.StackFrameDisplayOptions): DisplayParts;
}
interface Loc {
    line: number;
    column?: number | undefined;
}
interface DescribedPath {
    // path(options?: StackFrameDisplayOptions): string;
    parts: (options?: interfaces.StackFrameDisplayOptions) => DisplayPathParts;
}
declare class DescribedModulePath implements DescribedPath {
    #private;
    readonly pkg: null;
    readonly type = "relative";
    constructor(path: string);
    parts(options?: interfaces.StackFrameDisplayOptions): DisplayPathParts;
}
declare class DescribedPackage implements DescribedPath {
    #private;
    readonly type = "package";
    constructor(scope: string, name: string, path: string);
    get pkg(): string;
    parts(): DisplayPathParts;
}
interface ErrorWithStack extends Error {
    stack: string;
}
interface StackStatics {
    readonly EMPTY: StackProtocol;
    create: (this: void, internal?: number) => StackProtocol;
    fromStack: (stack: string) => StackProtocol;
    from: ((error: ErrorWithStack) => StackProtocol) & ((error: unknown) => StackProtocol | null);
    id: (this: void, description?: string | Description | {
        id: ReactiveId;
    }) => ReactiveId;
    description: (this: void, args: DescriptionArgs & {
        fromUser?: string | DescriptionDetails | interfaces.Description | undefined;
    }, internal?: number) => interfaces.Description;
    desc: (type: interfaces.DescriptionType, fromUser?: string | DescriptionDetails | interfaces.Description | undefined, internal?: number | undefined) => interfaces.Description;
    fromCaller: (this: void, internal?: number) => StackProtocol;
    replaceFrames: (error: unknown, fromStack: StackProtocol) => void;
    /**
     * Erase an abstraction from the call stack so the test error points at the user code, rather than
     * the abstraction's code.
     *
     * Call a callback, and if the callback throws an exception, remove the current frame and all of the
     * frames invoked by the current frame from the call stack.
     *
     * If you want to erase additional **caller** frames (because the code that calls the callback is
     * not the direct call site from user code), you can specify an additional number of frames to erase
     * using the `internal` parameter.
     */
    entryPoint: <T>(this: void, callback: () => T, options?: {
        internal?: number;
        stack?: StackProtocol;
    }) => T;
}
declare const Stack: StackStatics;
type Stack = interfaces.Stack;
declare const entryPoint: <T>(this: void, callback: () => T, options?: {
    internal?: number;
    stack?: StackProtocol;
}) => T;
declare function entryPointFn<F extends UnknownFn>(fn: F, options?: {
    stack: Stack;
}): F;
declare function entryPoints<Funcs extends object>(funcs: Funcs, options?: {
    stack: Stack;
}): Funcs;
/** This should be convertable to something like Description.EMPTY in prod builds  */
declare const descriptionFrom: (this: void, args: DescriptionArgs & {
    fromUser?: string | DescriptionDetails | interfaces.Description | undefined;
}, internal?: number) => interfaces.Description;
declare const Desc: (type: interfaces.DescriptionType, fromUser?: string | DescriptionDetails | interfaces.Description | undefined, internal?: number | undefined) => interfaces.Description;
/**
 * If it isn't already removed, this should be convertable to getID in prod builds
 */
declare const idFrom: (this: void, description?: string | Description | {
    id: ReactiveId;
}) => ReactiveId;
declare const callerStack: (this: void, internal?: number) => StackProtocol;
declare function isErrorWithStack(error: unknown): error is ErrorWithStack;
interface ReactiveProtocolStatics {
    dependencies: (reactive: ReactiveProtocol) => Iterable<MutableInternals>;
}
interface OperationInfo<I extends ReactiveInternals> {
    readonly at: Timestamp;
    readonly for: I;
    readonly caller: Stack$0;
}
declare class LeafOperation<I extends ReactiveInternals> {
    #private;
    constructor(data: OperationInfo<I>);
    get at(): Timestamp;
    get caller(): Stack$0;
    get for(): I;
}
declare class CellConsumeOperation extends LeafOperation<MutableInternals> {
    readonly type = "cell:consume";
}
declare class CellUpdateOperation extends LeafOperation<MutableInternals> {
    readonly type = "cell:update";
}
interface FrameConsumeInfo extends OperationInfo<CompositeInternals> {
    readonly diff: Diff<MutableInternals>;
    readonly frame: Frame;
}
declare class FrameConsumeOperation extends LeafOperation<CompositeInternals> {
    #private;
    readonly type = "frame:consume";
    constructor(data: FrameConsumeInfo);
    get diff(): Diff<MutableInternals>;
    get frame(): Frame;
}
declare class MutationLog {
    #private;
    readonly type = "mutation";
    // This makes `DebugOperation.for` ==== `ReactiveInternals | undefined`, which makes it possible
    // to easily compare the `for` value without a lot of extra type shenanigans.
    readonly for: ReactiveInternals | undefined;
    constructor(at: Timestamp, description: string, parent: MutationLog | null);
    get at(): Timestamp;
    add(child: DebugOperation): void;
}
type DebugOperation = CellConsumeOperation | CellUpdateOperation | FrameConsumeOperation | MutationLog;
interface Flush {
    readonly history: DebugOperation[];
    for: (reactive: ReactiveProtocol) => readonly DebugOperation[];
}
type DebugListener = InstanceType<typeof DebugTimeline.DebugListener>;
type DebugFilter = {
    type: "by-reactive";
    reactive: ReactiveProtocol;
} | {
    type: "all";
} | {
    type: "none";
};
declare class DebugTimeline {
    #private;
    static Flush: {
        new (history: DebugOperation[]): {
            readonly history: DebugOperation[];
            for(reactive: ReactiveProtocol): DebugOperation[];
        };
    };
    static DebugListener: {
        new (timeline: DebugTimeline, notify: () => void, filter: DebugFilter): {
            "__#3916@#timeline": DebugTimeline;
            "__#3916@#offset": number;
            "__#3916@#filter": DebugFilter;
            "__#3916@#notify": () => void;
            update(filter: DebugFilter): void;
            flush(): DebugOperation[];
            detach(): void;
        };
        offset(this: void, listener: {
            "__#3916@#timeline": DebugTimeline;
            "__#3916@#offset": number;
            "__#3916@#filter": DebugFilter;
            "__#3916@#notify": () => void;
            update(filter: DebugFilter): void;
            flush(): DebugOperation[];
            detach(): void;
        }): number;
        create(timestamp: {
            now: () => Timestamp;
        }, statics: ReactiveProtocolStatics): DebugTimeline;
        notify(this: void, listener: {
            "__#3916@#timeline": DebugTimeline;
            "__#3916@#offset": number;
            "__#3916@#filter": DebugFilter;
            "__#3916@#notify": () => void;
            update(filter: DebugFilter): void;
            flush(): DebugOperation[];
            detach(): void;
        }): void;
    };
    static create(timestamp: {
        now: () => Timestamp;
    }, statics: ReactiveProtocolStatics): DebugTimeline;
    private constructor();
    notify(): void;
    attach(notify: () => void, options?: {
        filter: DebugFilter | "all" | "none";
    }): DebugListener;
    consumeCell(internals: MutableInternals, caller: Stack$0): void;
    consumeFrame(frame: Frame, diff: Diff<MutableInternals>, caller: Stack$0): void;
    updateCell(cell: MutableInternals, caller: Stack$0): void;
    mutation<T>(description: string, callback: () => T): T;
}
type Leaf = string;
type ParentNode = [
    label: string,
    ...children: Node[]
];
type Node = Leaf | ParentNode;
declare class Root {
    #private;
    constructor(root: Node[]);
    format(): string;
}
declare function Tree(...root: Node[]): Root;
declare const defaultDescription: import("@starbeam/interfaces").Description;
export { Description, REUSE_ID, DisplayStructOptions, DisplayStruct, Inspect, DEBUG, DEBUG_NAME, INSPECT, inspect, inspector, logged, Logger, LOGGER, LogLevel, Block, Fragment, Message, Style$0 as Style, Styled, Styles, DisplayParts, describeModule, callerStack, Desc, descriptionFrom, entryPoint, entryPointFn, entryPoints, idFrom, isErrorWithStack, Stack, CellConsumeOperation, CellUpdateOperation, DebugFilter, DebugListener, DebugOperation, Flush, FrameConsumeOperation, MutationLog, DebugTimeline, Tree, defaultDescription };
export type { ApiDetails, DescriptionArgs, DescriptionDetails, DescriptionParts, DescriptionType, DetailDescription, DetailsPart, MemberDescription } from "@starbeam/interfaces";
//# sourceMappingURL=index.d.cts.map