import { isTag } from './shared';

export declare function hasAsyncOpcodes(): boolean;
export declare function markOpcodeAsync(op: tagOp): void;
export declare const opsForTag: Map<number, Array<tagOp>>;
export declare const tagsToRevalidate: Set<Cell>;
export declare const relatedTags: Map<number, Set<MergedCell>>;
export declare function releaseOpArray(arr: Array<tagOp>): void;
export declare const DEBUG_MERGED_CELLS: Set<MergedCell>;
export declare const DEBUG_CELLS: Set<Cell<unknown>>;
export declare function currentGlobalRevision(): number;
export declare function bumpGlobalRevision(): number;
export declare const cellsMap: WeakMap<object, Map<string | number | symbol, Cell<unknown>>>;
export declare function getCells(): Cell<unknown>[];
export declare function getMergedCells(): MergedCell[];
export declare function tracked(klass: any, key: string, descriptor?: PropertyDescriptor & {
    initializer?: () => any;
}): void;
export type AnyCell = Cell | MergedCell;
export declare function isRendering(): boolean;
export declare function setIsRendering(value: boolean): void;
export declare class Cell<T extends unknown = unknown> {
    private __value;
    id: number;
    _revision: number;
    toHTML: () => string;
    [Symbol.toPrimitive](): T;
    _debugName?: string | undefined;
    [isTag]: boolean;
    constructor(value: T, debugName?: string);
    get _value(): T;
    set _value(v: T);
    get value(): T;
    set value(value: T);
    update(value: T): void;
}
export declare class LazyCell<T extends unknown = unknown> extends Cell<T> {
    private __isResolved;
    private __lazyValue;
    private __fn;
    constructor(fn: () => T, debugName?: string);
    get _value(): T;
    set _value(v: T);
}
export declare function listDependentCells(cells: Array<AnyCell>, cell: MergedCell): string;
export declare function opsFor(cell: AnyCell): tagOp[];
export declare function relatedTagsForCell(cell: Cell): Set<MergedCell>;
export declare function getTagId(): number;
export declare function tagsFromRange(start: number, end?: number): Cell<unknown>[];
export declare class MergedCell {
    fn: Fn | Function;
    toHTML: () => string;
    isConst: boolean;
    isDestroyed: boolean;
    id: number;
    [Symbol.toPrimitive](): any;
    _debugName?: string | undefined;
    relatedCells: Set<Cell> | null;
    [isTag]: boolean;
    constructor(fn: Fn | Function, debugName?: string);
    destroy(): void;
    get value(): any;
}
export type tagOp = (...values: unknown[]) => Promise<void> | void;
/**
 * Executes all opcodes for a tag.
 *
 * `awaitAsync = false` is the synchronous fast path with no Promise allocation.
 * `awaitAsync = true` preserves async opcode semantics and awaits marked async ops.
 */
export declare function executeTag(tag: Cell | MergedCell, awaitAsync: true): Promise<void>;
export declare function executeTag(tag: Cell | MergedCell, awaitAsync: false): void;
export declare function executeTag(tag: Cell | MergedCell, awaitAsync?: boolean): Promise<void> | void;
export declare function executeTagSync(tag: Cell | MergedCell): void;
export declare function lazyRawCellFor<T extends object, K extends keyof T>(obj: T, key: K, init?: () => T[K]): Cell<T[K]>;
export declare function rawCellFor<T extends object, K extends keyof T>(obj: T, key: K): Cell<T[K]>;
export declare function cellFor<T extends object, K extends keyof T>(obj: T, key: K, skipDefine?: boolean): Cell<T[K]>;
type Fn = () => unknown;
export declare function formula(fn: Function | Fn, debugName?: string): MergedCell;
/**
 * `cached(fn)` — memoizing derivation.
 *
 * Like `formula(fn)` but records the last computed value and the set of tracked
 * cells observed during that computation. A subsequent `value` read returns the
 * cached value as long as none of those cells has bumped its `_revision` since
 * the last compute. When the observed deps are dirty, the underlying fn() is
 * re-executed exactly once, freshly collecting deps.
 *
 * Both `cached.value` (public) and the inner MergedCell's `value` (invoked by
 * `executeTag` during DOM sync) route through the same memoized path, so the
 * user getter runs at most once per dep-revision epoch even when the sync
 * pipeline re-executes the tag directly.
 *
 * The returned object is tag-like: it participates in GXT's tracker frames, so
 * a parent formula that reads `cached.value` still records a dependency on the
 * underlying cells (we re-add them to the ambient tracker on every read).
 */
export interface CachedCell<T = unknown> {
    readonly value: T;
    readonly tag: MergedCell;
    invalidate(): void;
    [isTag]: true;
}
export declare function cached<T>(fn: () => T, debugName?: string): CachedCell<T>;
export declare function deepFnValue(fn: Function | Fn): any;
export declare function cell<T>(value: T, debugName?: string): Cell<T>;
export declare function inNewTrackingFrame(callback: () => void): void;
export declare function getTracker(): Set<Cell<unknown>> | null;
export declare function setTracker(tracker: Set<Cell> | null): void;
export {};
