/**
 * useTraitStateMachine Hook
 *
 * Manages trait state machines with event-driven transitions.
 * Subscribes to eventBus events and executes effects when transitions occur.
 *
 * CONSOLIDATED RUNTIME:
 * - Uses StateMachineManager from @almadar/runtime for state management
 * - Uses the same state machine logic as the server runtime (OrbitalServerRuntime)
 * - Ensures consistent behavior between client preview and server execution
 *
 * SLOT MANAGEMENT:
 * - Collects all render-ui effects from a transition, groups by slot
 * - Sets each slot's patterns array atomically via SlotsActions
 * - No stacking logic, no priority system — transition produces complete slot content
 *
 * @packageDocumentation
 */
import type { EventPayload } from '@almadar/core';
import { type TraitState } from '@almadar/runtime';
import type { ResolvedTraitBinding } from './types';
import type { useUISlots } from '../context/UISlotContext';
export type { TraitState };
export interface TraitStateMachineResult {
    /** Current state for each trait */
    traitStates: Map<string, TraitState>;
    /** Send an event to trigger a transition */
    sendEvent: (eventKey: string, payload?: EventPayload) => void;
    /** Get current state for a specific trait */
    getTraitState: (traitName: string) => TraitState | undefined;
    /** Check if a trait can handle an event from its current state */
    canHandleEvent: (traitName: string, eventKey: string) => boolean;
}
export interface UseTraitStateMachineOptions {
    /**
     * Callback invoked after each event is processed (for server forwarding).
     *
     * `dispatchedOrbitals` is the set of orbital names whose traits actually
     * executed a transition for this event. The server-bridge fan-out should
     * be scoped to this set; sending the event to other orbitals fires
     * same-named transitions in unrelated orbitals and stacks their UI into
     * the wrong slot (gap #11 in `docs/Almadar_Std_Verification.md`). Empty
     * set means no local transition matched — leave the legacy fallback to
     * the consumer.
     */
    onEventProcessed?: (eventKey: string, payload?: EventPayload, dispatchedOrbitals?: Set<string>) => void | Promise<void>;
    /** Router navigate function for navigate effects */
    navigate?: (path: string, params?: Record<string, unknown>) => void;
    /** Notification function for notify effects */
    notify?: (message: string, type?: 'success' | 'error' | 'warning' | 'info') => void;
    /**
     * Offline-preview persistence layer. When set, the client runtime merges
     * `@almadar/runtime` `createServerEffectHandlers` on top of the default
     * client handlers so `fetch` / `persist` / `set` / `ref` / `deref` /
     * `swap!` / `atomic` / `callService` run against this adapter — matching
     * what `OrbitalServerRuntime` would do on the server. Left unset in the
     * server-bridge path; effects there flow to the real server.
     */
    persistence?: import('@almadar/runtime').PersistenceAdapter;
    /** Optional consumer `call-service` hook forwarded to the mock server handlers. */
    callService?: (service: string, action: string, params: unknown) => Promise<unknown>;
    /**
     * Trait configs keyed by trait name. Threaded into setTraitConfig so
     * `@config.X` resolves inside guard expressions on the client. Page-level
     * `ResolvedTraitBinding`s often arrive without a config (the orbital-level
     * config doesn't propagate through `@almadar/core`'s page resolver), so the
     * caller assembles this map from the orbital schema directly.
     */
    traitConfigsByName?: Record<string, import('@almadar/core').TraitConfig>;
    /**
     * Trait → orbital map built from `schema.orbitals[].traits[]` by the
     * caller. Threaded down so bus emits (`UI:Orbital.Trait.Event`) and
     * subscriptions can carry the qualified `Orbital.Trait` scope —
     * gap #13 unification. Same mechanism as `traitConfigsByName`: the
     * orbital boundary doesn't propagate through `@almadar/core`'s
     * `ResolvedTraitBinding`, so the caller assembles the map directly.
     */
    orbitalsByTrait?: Record<string, string>;
    /**
     * Set of trait names referenced via `@trait.X` by some sibling
     * layout in the resolved schema. Slot writes from these traits go
     * to the per-trait sidecar via `uiSlots.updateTraitContent`; the
     * layout owns the slot and embeds via `<TraitFrame>`. Mirrors
     * compiled-path codegen semantics.
     */
    embeddedTraits?: ReadonlySet<string>;
}
/**
 * useTraitStateMachine - Manages state machines for multiple traits
 *
 * Uses the shared StateMachineManager for consistent behavior with server runtime.
 * Collects render-ui effects per transition and sets slot content atomically.
 *
 * Slot writes go directly to `useUISlots` (the canonical store the DOM
 * reads from) instead of routing through the now-removed `SlotsContext`
 * + `SlotBridge` mirror. Trait names listed in `embeddedTraits` are
 * referenced via `@trait.X` by some sibling layout's render-ui — for
 * those, slot writes update the per-trait sidecar (via
 * `updateTraitContent`) so `<TraitFrame>` can pick them up without the
 * atom landing as a separate slot source. Mirrors compiled-path
 * codegen, where atom views are inlined as JSX inside the layout's
 * pattern rather than each writing a shared slot.
 */
export declare function useTraitStateMachine(traitBindings: ResolvedTraitBinding[], uiSlots: ReturnType<typeof useUISlots>, options?: UseTraitStateMachineOptions): TraitStateMachineResult;
export default useTraitStateMachine;
