import { Effect } from 'effect';
import type { Ref } from 'vue';
import type { FieldValue } from '../schema.js';
import type { FormStateBag } from './state.js';
/**
 * Structural equality over JSON-ish values (the shape a derived expression
 * returns: primitives, arrays, plain objects, `Date`). It is load-bearing: a
 * derived value writes its result back into form state, which re-triggers the
 * expression; a shallow `Object.is` would see a fresh-but-equal array/object
 * as a change and loop forever. With deep equality a settled expression's
 * re-write is a no-op and cascades converge.
 */
export declare function deepEqual(a: unknown, b: unknown): boolean;
export type DerivedQuiescence = {
    /** Count of derived-value evaluations currently in flight, form-wide. */
    inFlight: Ref<number>;
    begin: () => void;
    end: () => void;
    /** Resolves once every derived value — including cascades — has settled. */
    settled: () => Promise<void>;
};
/**
 * Provide the form-wide derivation quiescence tracker. Called once at the
 * top-level form host; nested list rows inherit it, so `settled()` waits on
 * every derived value in the form — top-level and row-level alike.
 */
export declare function provideDerivedQuiescence(): DerivedQuiescence;
/**
 * Inject the form's quiescence tracker. Falls back to a standalone instance
 * when mounted outside a form host.
 */
export declare function useDerivedQuiescence(): DerivedQuiescence;
export type DerivedOptions = {
    /**
     * Every field of this form unit. Derived values run regardless of layout
     * placement or `hidden` state — a hidden derived field still feeds
     * submission.
     */
    fields: () => ReadonlyArray<FieldValue>;
    /** Evaluate a derived expression against the host's CEL context. */
    evaluate: (expression: string) => Effect.Effect<unknown, unknown>;
    /**
     * Derived values start only after this resolves — the top-level form passes
     * its `initial` seed promise so first-paint uses the seed, then derivation
     * takes over; list rows pass an already-resolved promise.
     */
    ready: Promise<void>;
    /**
     * The form unit's state bag — the top form's or a list row's. Passed
     * explicitly rather than injected: `useDerived` runs in the very component
     * that provides the bag, and a component cannot inject its own provide.
     */
    formState: FormStateBag;
    /** The form-wide derivation quiescence tracker (provided at the top form). */
    quiescence: DerivedQuiescence;
};
/**
 * Maintains every derived field's value in this form unit. A field carrying a
 * `derived` config is computed from a CEL expression and written back to its
 * `binding`, recomputed whenever committed form state changes. Two modes:
 *
 * - `formula` — the field is read-only; its value is *always* the expression's
 *   result.
 * - `prefill` — the field stays editable; the expression only fills it while
 *   the user has not touched the binding. Once `formState.isDirty(binding)` is
 *   true the user has taken over and the expression no longer writes.
 *
 * Mounted by each form-unit host — the top form and every list row — so a row
 * derived value evaluates `item`/writes row state, a top-level one evaluates
 * `form`/writes form state, all sharing one quiescence tracker.
 */
export declare function useDerived(options: DerivedOptions): void;
