import { SenderHandler } from '@synnaxlabs/x';
import { PropsWithChildren, ReactElement } from 'react';
import { z } from 'zod';
import { AetherMessage, MainMessage } from './message';
import { state } from '../state';
type RawSetArg<S extends z.ZodType<state.State>> = (z.input<S> | z.infer<S>) | ((prev: z.infer<S>) => z.input<S> | z.infer<S>);
/**
 * return value of the create function in the Aether context.
 * Provides methods to manage the lifecycle of an Aether component.
 */
export interface CreateReturn {
    /**
     * Updates the state of the component and optionally transfers objects to the worker thread.
     * @param state - The new state to set on the component
     * @param transfer - Optional array of Transferable objects to be transferred to the worker
     */
    setState: (state: state.State, transfer?: Transferable[]) => void;
    /**
     * Deletes the component from the Aether tree, triggering cleanup
     * on the worker thread.
     */
    delete: () => void;
}
/**
 * Interface representing the value provided by the Aether context.
 * Used to create and manage Aether components in the component tree.
 */
export interface ContextValue {
    /** The current path in the Aether component tree */
    path: string[];
    /**
     * Creates a new Aether component in the tree
     * @param type - The type identifier for the component
     * @param path - The path where the component should be created
     * @param onReceive - Optional callback for handling state updates from the worker
     * @returns An object with methods to manage the component's lifecycle
     */
    create: (type: string, path: string[], onReceive?: StateHandler) => CreateReturn;
}
/**
 * Props for the Aether Provider component that establishes the Aether context.
 */
export interface ProviderProps extends PropsWithChildren {
    /** Unique identifier for the worker instance */
    workerKey: string;
    /** Optional worker handler for managing communication between main and worker threads */
    worker?: SenderHandler<MainMessage, AetherMessage>;
}
export declare const Provider: ({ workerKey, worker: propsWorker, children, }: ProviderProps) => ReactElement;
export declare const useContext: () => ContextValue;
export interface UseLifecycleReturn<S extends z.ZodType<state.State>> {
    path: string[];
    setState: (state: RawSetArg<S>, transfer?: Transferable[]) => void;
}
interface UseLifecycleProps<S extends z.ZodType> {
    type: string;
    schema: S;
    aetherKey?: string;
    initialState: z.input<S>;
    initialTransfer?: Transferable[];
    onReceive?: StateHandler<z.infer<S>>;
}
/**
 * A low-level hook that manages the lifecycle of an Aether component. This hook handles
 * component creation, state updates, and cleanup in the Aether worker architecture.
 *
 * @template S - A Zod schema type that defines the shape and validation of the component's state
 *
 * @param props - Configuration options for the lifecycle hook
 * @param props.type - A string identifier for the component type. Must correspond to a registered
 *                     component type in the worker thread's registry.
 * @param props.schema - A Zod schema that defines the shape and validation of the component's state.
 *                       Used to validate state during transfer between main and worker threads.
 * @param props.aetherKey - Optional unique identifier for the component. If not provided,
 *                         a unique key will be generated automatically.
 * @param props.initialState - The initial state value that conforms to the provided schema.
 * @param props.initialTransfer - Optional array of Transferable objects to be transferred
 *                               along with the initial state.
 * @param props.onReceive - Optional callback function that handles state updates received
 *                         from the worker thread.
 *
 * @returns An object containing:
 *          - path: string[] - The full path to this component in the Aether component tree
 *          - setState: (state: z.input<S>, transfer?: Transferable[]) => void - A function
 *            to update the component's state and optionally transfer objects to the worker
 *
 * @example
 * ```typescript
 * const MyComponent = () => {
 *   const { path, setState } = useLifecycle({
 *     type: "MyComponentType",
 *     schema: z.object({ count: z.number() }),
 *     initialState: { count: 0 },
 *     onReceive: (state) => console.log("Received state:", state)
 *   });
 *
 *   return <button onClick={() => setState({ count: count + 1 })}>Increment</button>;
 * };
 * ```
 *
 * @remarks
 * - This hook must be used within an Aether.Provider context
 * - The hook ensures proper cleanup on component unmount
 * - State updates are validated against the provided schema before being sent to the worker
 * - The hook uses synchronous initialization to ensure parent components are created
 *   before their children
 * - Changes to initialState after the first render will not affect the component's state.
 *   Use setState to update the state instead.
 */
export declare const useLifecycle: <S extends z.ZodType<state.State>>({ type, aetherKey, initialState, schema, initialTransfer, onReceive, }: UseLifecycleProps<S>) => UseLifecycleReturn<S>;
/** Props for components that use Aether functionality */
export interface ComponentProps {
    /** Optional unique identifier for the Aether component */
    aetherKey?: string;
}
/** Props for the use hook that manages Aether component lifecycle */
export interface UseProps<S extends z.ZodType> extends Omit<UseLifecycleProps<S>, "onReceive"> {
    /** Optional callback for handling state changes from the Aether component */
    onAetherChange?: (state: z.infer<S>) => void;
}
interface ComponentContext {
    path: string[];
}
/**
 * Return type for the use hook, providing access to component context, state, and state setter
 */
export type UseReturn<S extends z.ZodType<state.State>> = [
    ComponentContext,
    z.infer<S>,
    (state: RawSetArg<S>, transfer?: Transferable[]) => void
];
/**
 * Props for the useUnidirectional hook that only propagates state to the Aether component
 */
export interface UseUnidirectionalProps<S extends z.ZodType> extends Pick<UseLifecycleProps<S>, "schema" | "aetherKey"> {
    /** The type identifier for the Aether component */
    type: string;
    /** The current state to propagate to the Aether component */
    state: z.input<S>;
}
/***
 * A simpler version of {@link use} that assumes the caller only wants to propagate
 * state to the aether component, and not receive state from the aether component.
 */
export declare const useUnidirectional: <S extends z.ZodType<state.State>>({ state, ...rest }: UseUnidirectionalProps<S>) => ComponentContext;
/**
 * Use creates a new aether component with a unique key and type.
 *
 * @param props.type - The type of the component. Aether will use this to instantiate
 * the correct component type on the worker thread. A constructor for this type must
 * exist on the registry passed into aether.render on the worker thread.
 * @param props.aetherKey - A unique key for the component that is used to identify it
 * in the aether component tree. We recommend using `Aether.wrap` to create unique keys.
 * @param props.schema - The zod schema for the component's state. Used to validate state
 * changes on transfer to and from the worker thread.
 * @param props.initialState - The initial state for the component. Note that this state
 * is only used on the first render, and any changes to this value will not be reflected
 * in the component's state. To alter the component's state, use the setState function
 * returned by the hook.
 * @returns A triplet with the following values:
 * 1. An object containing metadata about the created component. This object contains a
 *    path property, which is an array of strings representing the path to the component
 *    in the aether component tree.
 * 2. The component's current state. This is synchronized with the worker thread, and
 * can be updated by both the worker and the main thread.
 * 3. A function that can be used to update the component's state. This function takes
 * in both the next state and an optional array of transferable objects. The next state
 * can be either a new state, or a function that takes in the current state and returns
 * the next state. This function is impure, and will update the component's state on the
 * worker thread.
 */
export declare const use: <S extends z.ZodType<state.State>>(props: UseProps<S>) => UseReturn<S>;
type StateHandler<S = unknown> = (state: S) => void;
/**
 * Props for the Composite component that establishes child components in the Aether tree
 */
export interface CompositeProps extends PropsWithChildren {
    /**
     * The path in the Aether component tree where children should be established
     */
    path: string[];
}
/**
 * Composite establishes all children as child components of the current component. The
 * provide path should match the path returned by the {@link use} hook. Any children
 * of this component will be added to the `children` property of the component on the
 * worker tree.
 *
 * Naturally, composites can be nested within each other. Child components that are
 */
export declare const Composite: import('react').MemoExoticComponent<({ children, path }: CompositeProps) => ReactElement>;
export {};
//# sourceMappingURL=main.d.ts.map