import { Alepha, Async, Atom, Computed, Hook, Hooks, Service, State, Static, TAtomObject } from "alepha";
import React, { DependencyList, ErrorInfo, PropsWithChildren, ReactNode } from "react";
import { DurationLike } from "alepha/datetime";
import { ClientScope, HttpVirtualClient } from "alepha/server/links";
//#region ../../src/react/core/components/ClientOnly.d.ts
interface ClientOnlyProps {
  fallback?: ReactNode;
  disabled?: boolean;
}
/**
 * A small utility component that renders its children only on the client side.
 *
 * Optionally, you can provide a fallback React node that will be rendered.
 *
 * You should use this component when
 * - you have code that relies on browser-specific APIs
 * - you want to avoid server-side rendering for a specific part of your application
 * - you want to prevent pre-rendering of a component
 *
 * @example
 * ```tsx
 * import { ClientOnly } from "alepha/react";
 *
 * const MyComponent = () => {
 *   // Avoids SSR issues with Date API
 *   return (
 *     <ClientOnly>
 *       {new Date().toLocaleTimeString()}
 *     </ClientOnly>
 *   );
 * }
 * ```
 */
declare const ClientOnly: (props: PropsWithChildren<ClientOnlyProps>) => ReactNode;
//#endregion
//#region ../../src/react/core/components/ErrorBoundary.d.ts
/**
 * Props for the ErrorBoundary component.
 */
interface ErrorBoundaryProps {
  /**
   * Fallback React node to render when an error is caught.
   * If not provided, a default error message will be shown.
   */
  fallback: (error: Error, reset: () => void) => ReactNode;
  /**
   * Optional callback that receives the error and error info.
   * Use this to log errors to a monitoring service.
   */
  onError?: (error: Error, info: ErrorInfo) => void;
  /**
   * Clear a caught error whenever any of these values changes (compared with
   * `Object.is`, positionally).
   *
   * A boundary that catches has to be told when the reason to fail is gone —
   * otherwise the fallback latches and every later render keeps showing the
   * stale error. The router passes the current path, so navigating away from a
   * page that threw recovers on its own.
   *
   * Unlike remounting via `key`, this clears the error WITHOUT tearing down the
   * children, so unrelated component state survives an ordinary navigation.
   */
  resetKeys?: readonly unknown[];
}
/**
 * State of the ErrorBoundary component.
 */
interface ErrorBoundaryState {
  error?: Error;
}
/**
 * A reusable error boundary for catching rendering errors in any part of the React component tree.
 *
 * It's already included in the Alepha React framework when using page or layout components.
 */
declare class ErrorBoundary extends React.Component<PropsWithChildren<ErrorBoundaryProps>, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps);
  /**
   * Update state so the next render shows the fallback UI.
   */
  static getDerivedStateFromError(error: Error): ErrorBoundaryState;
  /**
   * Lifecycle method called when an error is caught.
   * You can log the error or perform side effects here.
   */
  componentDidCatch(error: Error, info: ErrorInfo): void;
  /**
   * Recover once the caller signals the failing input is gone.
   */
  componentDidUpdate(prevProps: PropsWithChildren<ErrorBoundaryProps>): void;
  protected hasResetKeyChanged(previous: readonly unknown[] | undefined, next: readonly unknown[] | undefined): boolean;
  render(): ReactNode;
}
//#endregion
//#region ../../src/react/core/contexts/AlephaContext.d.ts
/**
 * React context to provide the Alepha instance throughout the component tree.
 */
declare const AlephaContext: import("react").Context<Alepha | undefined>;
//#endregion
//#region ../../src/react/core/contexts/AlephaProvider.d.ts
interface AlephaProviderProps {
  children: ReactNode;
  onError: (error: Error) => ReactNode;
  onLoading: () => ReactNode;
}
/**
 * AlephaProvider component to initialize and provide Alepha instance to the app.
 *
 * This isn't recommended for apps using `alepha/react/router`, as Router will handle this for you.
 */
declare const AlephaProvider: (props: AlephaProviderProps) => string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
//#endregion
//#region ../../src/react/core/hooks/useAction.d.ts
/**
 * Hook for handling async actions with automatic error handling and event emission.
 *
 * By default, prevents concurrent executions - if an action is running and you call it again,
 * the second call will be ignored. Use `debounce` option to delay execution instead.
 *
 * Emits lifecycle events:
 * - `react:action:begin` - When action starts
 * - `react:action:success` - When action completes successfully
 * - `react:action:error` - When action throws an error
 * - `react:action:end` - Always emitted at the end
 *
 * @example Basic usage
 * ```tsx
 * const action = useAction({
 *   handler: async (data) => {
 *     await api.save(data);
 *   }
 * }, []);
 *
 * <button onClick={() => action.run(data)} disabled={action.loading}>
 *   Save
 * </button>
 * ```
 *
 * @example With debounce (search input)
 * ```tsx
 * const search = useAction({
 *   handler: async (query: string) => {
 *     await api.search(query);
 *   },
 *   debounce: 300 // Wait 300ms after last call
 * }, []);
 *
 * <input onChange={(e) => search.run(e.target.value)} />
 * ```
 *
 * @example Run on component mount
 * ```tsx
 * const fetchData = useAction({
 *   handler: async () => {
 *     const data = await api.getData();
 *     return data;
 *   },
 *   runOnInit: true // Runs once when component mounts
 * }, []);
 * ```
 *
 * @example Run periodically (polling)
 * ```tsx
 * const pollStatus = useAction({
 *   handler: async () => {
 *     const status = await api.getStatus();
 *     return status;
 *   },
 *   runEvery: 5000 // Run every 5 seconds
 * }, []);
 *
 * // Or with duration tuple
 * const pollStatus = useAction({
 *   handler: async () => {
 *     const status = await api.getStatus();
 *     return status;
 *   },
 *   runEvery: [30, 'seconds'] // Run every 30 seconds
 * }, []);
 * ```
 *
 * @example With AbortController
 * ```tsx
 * const fetch = useAction({
 *   handler: async (url, { signal }) => {
 *     const response = await fetch(url, { signal });
 *     return response.json();
 *   }
 * }, []);
 * // Automatically cancelled on unmount or when new request starts
 * ```
 *
 * @example With error handling
 * ```tsx
 * const deleteAction = useAction({
 *   handler: async (id: string) => {
 *     await api.delete(id);
 *   },
 *   onError: (error) => {
 *     if (error.code === 'NOT_FOUND') {
 *       // Custom error handling
 *     }
 *   }
 * }, []);
 *
 * {deleteAction.error && <div>Error: {deleteAction.error.message}</div>}
 * ```
 *
 * @example Global error handling
 * ```tsx
 * // In your root app setup
 * alepha.events.on("react:action:error", ({ error }) => {
 *   toast.danger(error.message);
 *   Sentry.captureException(error);
 * });
 * ```
 */
declare function useAction<Args extends any[], Result = void>(options: UseActionOptions<Args, Result>, deps: DependencyList): UseActionReturn<Args, Result>;
/**
 * Context object passed as the last argument to action handlers.
 * Contains an AbortSignal that can be used to cancel the request.
 */
interface ActionContext {
  /**
   * AbortSignal that can be passed to fetch or other async operations.
   * The signal will be aborted when:
   * - The component unmounts
   * - A new action is triggered (cancels previous)
   * - The cancel() method is called
   *
   * @example
   * ```tsx
   * const action = useAction({
   *   handler: async (url, { signal }) => {
   *     const response = await fetch(url, { signal });
   *     return response.json();
   *   }
   * }, []);
   * ```
   */
  signal: AbortSignal;
}
interface UseActionOptions<Args extends any[] = any[], Result = any> {
  /**
   * The async action handler function.
   * Receives the action arguments plus an ActionContext as the last parameter.
   */
  handler: (...args: [...Args, ActionContext]) => Async<Result>;
  /**
   * Custom error handler. If provided, prevents default error re-throw.
   */
  onError?: (error: Error) => void | Promise<void>;
  /**
   * Custom success handler.
   */
  onSuccess?: (result: Result) => void | Promise<void>;
  /**
   * Optional identifier for this action (useful for debugging/analytics)
   */
  id?: string;
  name?: string;
  /**
   * Debounce delay in milliseconds. If specified, the action will only execute
   * after the specified delay has passed since the last call. Useful for search inputs
   * or other high-frequency events.
   *
   * @example
   * ```tsx
   * // Execute search 300ms after user stops typing
   * const search = useAction({ handler: search, debounce: 300 }, [])
   * ```
   */
  debounce?: number;
  /**
   * If true, the action will be executed once when the component mounts.
   *
   * @example
   * ```tsx
   * const fetchData = useAction({
   *   handler: async () => await api.getData(),
   *   runOnInit: true
   * }, []);
   * ```
   */
  runOnInit?: boolean;
  /**
   * If specified, the action will be executed periodically at the given interval.
   * The interval is specified as a DurationLike value (number in ms, Duration object, or [number, unit] tuple).
   *
   * @example
   * ```tsx
   * // Run every 5 seconds
   * const poll = useAction({
   *   handler: async () => await api.poll(),
   *   runEvery: 5000
   * }, []);
   * ```
   *
   * @example
   * ```tsx
   * // Run every 1 minute
   * const poll = useAction({
   *   handler: async () => await api.poll(),
   *   runEvery: [1, 'minute']
   * }, []);
   * ```
   */
  runEvery?: DurationLike;
}
interface UseActionReturn<Args extends any[], Result> {
  /**
   * Execute the action with the provided arguments.
   *
   * @example
   * ```tsx
   * const action = useAction({ handler: async (data) => { ... } }, []);
   * action.run(data);
   * ```
   */
  run: (...args: Args) => Promise<Result | undefined>;
  /**
   * Loading state - true when action is executing.
   */
  loading: boolean;
  /**
   * Error state - contains error if action failed, undefined otherwise.
   */
  error?: Error;
  /**
   * Cancel any pending debounced action or abort the current in-flight request.
   *
   * @example
   * ```tsx
   * const action = useAction({ ... }, []);
   *
   * <button onClick={action.cancel} disabled={!action.loading}>
   *   Cancel
   * </button>
   * ```
   */
  cancel: () => void;
  /**
   * The result data from the last successful action execution.
   */
  result?: Result;
}
//#endregion
//#region ../../src/react/core/hooks/useAlepha.d.ts
/**
 * Main Alepha hook.
 *
 * It provides access to the Alepha instance within a React component.
 *
 * With Alepha, you can access the core functionalities of the framework:
 *
 * - alepha.state() for state management
 * - alepha.inject() for dependency injection
 * - alepha.events.emit() for event handling
 * etc...
 */
declare const useAlepha: () => Alepha;
//#endregion
//#region ../../src/react/core/hooks/useClient.d.ts
/**
 * Hook to get a virtual client for the specified scope.
 *
 * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.
 */
declare const useClient: <T extends object>(scope?: ClientScope) => HttpVirtualClient<T>;
//#endregion
//#region ../../src/react/core/hooks/useComputed.d.ts
/**
 * Subscribes to a `$computed` value.
 *
 * `getSnapshot` always reads the dependency atoms **live** off the store —
 * never through a subscription-set dirty flag. A dirty flag is only ever
 * flipped by the `state:mutate` listener registered in `subscribe`, which
 * React wires up in a passive effect (after commit); `EventManager.emit` is
 * async on top of that. A mutation dispatched between the initial render and
 * that effect committing would be invisible to the flag, so `getSnapshot`
 * (including React's own post-subscribe consistency re-check) would keep
 * returning the stale pre-mutation value. See `useStore.ts` and
 * `useSelector.ts` for the same rationale.
 *
 * Referential stability for `useSyncExternalStore` comes from comparing the
 * *inputs* (the resolved values of the computed's transitive atom
 * dependencies) by identity, not from caching on a mount-time ref: when none
 * of the inputs changed since the last snapshot, the previous output
 * reference is returned as-is; when any input changed (or `target` itself
 * was swapped for a different `Computed`), the value is recomputed and a new
 * reference is cached.
 *
 * A `Computed` passed here should be declared at module scope, like an
 * atom — constructing one inline in a component body creates a new
 * instance every render, which (because `subscribe`/`getSnapshot` are keyed
 * on `target.key`, matching `useStore`/`useSelector`) is tolerated for
 * resubscription purposes, but any closures captured by that instance's
 * `get()` will be locked to whichever render first created the subscription
 * until `target.key` itself changes.
 *
 * ```tsx
 * const total = useComputed(cartTotal);
 * ```
 */
declare function useComputed<R>(target: Computed<R>): R;
//#endregion
//#region ../../src/react/core/hooks/useEvents.d.ts
/**
 * Allow subscribing to multiple Alepha events. See {@link Hooks} for available events.
 *
 * useEvents is fully typed to ensure correct event callback signatures.
 *
 * @example
 * ```tsx
 * useEvents(
 *   {
 *     "react:transition:begin": (ev) => {
 *       console.log("Transition began to:", ev.to);
 *     },
 *     "react:transition:error": {
 *       priority: "first",
 *       callback: (ev) => {
 *         console.error("Transition error:", ev.error);
 *       },
 *     },
 *   },
 *   [],
 * );
 * ```
 */
declare const useEvents: (opts: UseEvents, deps: DependencyList) => void;
type UseEvents = { [T in keyof Hooks]?: Hook<T> | ((payload: Hooks[T]) => Async<void>); };
//#endregion
//#region ../../src/react/core/hooks/useInject.d.ts
/**
 * Hook to inject a service instance.
 * It's a wrapper of `useAlepha().inject(service)` with a memoization.
 */
declare const useInject: <T extends object>(service: Service<T>) => T;
//#endregion
//#region ../../src/react/core/hooks/useQuery.d.ts
/**
 * Hook for declarative data fetching with automatic execution and refetch.
 *
 * Thin wrapper over {@link useAction}: it pre-applies `runOnInit: true`,
 * exposes the last result as `data`, and provides a stable `refetch()` to
 * re-run the query on demand. For optimistic mutations and side-effects,
 * use {@link useAction} directly — `useQuery` is for the read path.
 *
 * Caching, request deduplication, and AbortSignal cancellation come from
 * `useAction` + `HttpClient`. There is no separate cache layer — pass
 * `localCache` to your `HttpClient.fetch()`/`fetchAction()` call inside
 * the query handler if you want per-call caching.
 *
 * @example Basic
 * ```tsx
 * const client = useInject(HttpClient);
 * const { data, loading, error, refetch } = useQuery({
 *   handler: async ({ signal }) => {
 *     const res = await client.fetch("/api/users", { request: { signal } });
 *     return res.data;
 *   },
 * }, []);
 * ```
 *
 * @example Re-fetch when a dep changes
 * ```tsx
 * const { data } = useQuery({
 *   handler: async () => api.getUser(userId),
 * }, [userId]);
 * ```
 *
 * @example Polling
 * ```tsx
 * const { data } = useQuery({
 *   handler: async () => api.getStatus(),
 *   runEvery: [5, "seconds"],
 * }, []);
 * ```
 */
declare function useQuery<Result>(options: UseQueryOptions<Result>, deps: DependencyList): UseQueryReturn<Result>;
interface UseQueryOptions<Result> {
  /**
   * Async query handler. Receives an {@link ActionContext} with an
   * AbortSignal that fires on unmount, dependency change, or `cancel()`.
   */
  handler: (context: ActionContext) => Async<Result>;
  /**
   * Optional identifier (used in lifecycle events for debugging/analytics).
   */
  id?: string;
  /**
   * If `false`, skip automatic execution on mount and dep change. Use
   * `refetch()` to trigger manually. Defaults to `true`.
   */
  enabled?: boolean;
  /**
   * Initial value for `data` before the first successful fetch.
   */
  initialData?: Result;
  /**
   * Re-run periodically. See {@link useAction} `runEvery`.
   */
  runEvery?: DurationLike;
  /**
   * Debounce delay in milliseconds. See {@link useAction} `debounce`.
   */
  debounce?: number;
  /**
   * Called on success with the resolved value.
   */
  onSuccess?: (result: Result) => void | Promise<void>;
  /**
   * Custom error handler. If provided, prevents default error re-throw.
   */
  onError?: (error: Error) => void | Promise<void>;
}
interface UseQueryReturn<Result> {
  /**
   * The last successful result. `undefined` until the first fetch resolves
   * (or the value of `initialData` if provided).
   */
  data: Result | undefined;
  /**
   * Loading state — `true` while a fetch is in flight, and also from the
   * first render until the initial auto-run settles (for enabled queries
   * with no `initialData`), so a skeleton can render without a flash.
   */
  loading: boolean;
  /**
   * Error from the last failed fetch, if any.
   */
  error?: Error;
  /**
   * Re-run the query. The previous in-flight request, if any, is aborted.
   */
  refetch: () => Promise<Result | undefined>;
  /**
   * Abort the in-flight request without scheduling another.
   */
  cancel: () => void;
}
//#endregion
//#region ../../src/react/core/hooks/useSelector.d.ts
/**
 * Subscribes to a slice of an atom's state.
 *
 * Unlike {@link useStore}, which re-renders on every mutation of the atom,
 * `useSelector` re-renders only when the selected slice actually changes
 * according to `equality` (default: `Object.is`). Pass {@link shallowEqual}
 * when the selector builds a fresh object on each call.
 *
 * ```tsx
 * const theme = useSelector(uiAtom, (s) => s.theme);
 * ```
 */
declare function useSelector<T extends TAtomObject, R>(target: Atom<T>, select: (state: Static<T>) => R, equality?: (a: R, b: R) => boolean): R;
//#endregion
//#region ../../src/react/core/hooks/useStore.d.ts
/**
 * Hook to access and mutate the Alepha state.
 *
 * Reads through `useSyncExternalStore`, so the store — not a `useState` copy of
 * it — is the single source of truth. That is what keeps the value correct when
 * a mutation lands between render and effect-commit, when the component swaps
 * which `target` it watches, and when React renders concurrently (no tearing).
 */
declare function useStore<T extends TAtomObject>(target: Atom<T>, defaultValue?: Static<T>): UseStoreReturn<Static<T>>;
declare function useStore<Key extends keyof State>(target: Key, defaultValue?: State[Key]): UseStoreReturn<State[Key]>;
type UseStoreReturn<T> = [T, (value: T) => void];
//#endregion
//#region ../../src/react/core/utils/shallowEqual.d.ts
/**
 * Shallow structural equality over own enumerable keys.
 *
 * Intended as the `equality` argument of `useSelector` when the selector
 * builds a fresh object/array on every call (e.g. `(s) => ({ a: s.a })`).
 */
declare const shallowEqual: (a: unknown, b: unknown) => boolean;
//#endregion
//#region ../../src/react/core/index.d.ts
declare module "alepha" {
  interface Hooks {
    /**
     * Fires when a user action is starting.
     * Action can be a form submission, a route transition, or a custom action.
     */
    "react:action:begin": {
      type: string;
      id?: string;
    };
    /**
     * Fires when a user action has succeeded.
     * Action can be a form submission, a route transition, or a custom action.
     */
    "react:action:success": {
      type: string;
      id?: string;
    };
    /**
     * Fires when a user action has failed.
     * Action can be a form submission, a route transition, or a custom action.
     */
    "react:action:error": {
      type: string;
      id?: string;
      error: Error;
    };
    /**
     * Fires when a user action has completed, regardless of success or failure.
     * Action can be a form submission, a route transition, or a custom action.
     */
    "react:action:end": {
      type: string;
      id?: string;
    };
  }
}
/**
 * Full-stack React framework with server-side rendering.
 *
 * **Features:**
 * - React page routes with type-safe params
 * - Async action handler with loading/error/cancel states
 * - Type-safe HTTP client access
 * - Dependency injection in components
 * - Global state management
 * - Router navigation methods
 * - Current route state access
 * - Check if path is active
 * - URL query parameters
 * - Access route schema
 * - Subscribe to Alepha events
 * - Type-safe form handling with validation
 * - Error handling wrapper component
 * - Client-side only rendering component
 * - Server-side rendering with hydration
 * - Automatic code splitting
 * - Event system for action tracking
 *
 * @module alepha.react
 */
declare const AlephaReact: import("alepha").Service<import("alepha").Module>;
//#endregion
export { ActionContext, AlephaContext, AlephaProvider, AlephaProviderProps, AlephaReact, ClientOnly, type ClientOnlyProps, ErrorBoundary, type ErrorBoundaryProps, UseActionOptions, UseActionReturn, UseQueryOptions, UseQueryReturn, UseStoreReturn, shallowEqual, useAction, useAlepha, useClient, useComputed, useEvents, useInject, useQuery, useSelector, useStore };
//# sourceMappingURL=index.d.ts.map