import { DependencyList, RefObject, ReactNode, ReactElement } from 'react';
import { S as SockaContractBound, b as InferSockaPushHandlers, d as InferSockaSend, c as InferSockaPushPayload } from '../socka-report-error-BALZPjd1.js';
import { SockaSessionOptions, SockaSession, SockaConnectionStatus } from '../client/index.js';
import '@standard-schema/spec';

/** Options for {@link useSocka}. */
type UseSockaOptions<TContract extends SockaContractBound> = SockaSessionOptions<TContract>;
/**
 * Connects a {@link SockaSession} in an effect: rejects all pending calls and closes
 * the socket on cleanup or when `deps` change.
 */
declare function useSocka<TContract extends SockaContractBound>(options: UseSockaOptions<TContract>, deps: DependencyList): {
    ready: boolean;
    sessionRef: RefObject<SockaSession<TContract> | null>;
    status: SockaConnectionStatus;
    reconnecting: boolean;
    reconnectAttempt: number;
};

type UseSockaSessionOptions<TContract extends SockaContractBound> = Omit<UseSockaOptions<TContract>, "contract" | "pushHandlers"> & {
    pushHandlers?: Partial<InferSockaPushHandlers<TContract>>;
};
/**
 * Builds the same typed `send` object as {@link useSockaSession} from a live session ref.
 * Used by {@link useSockaSessionContext} so consumers do not open extra connections.
 */
declare function createSockaSendProxyFromSession<TContract extends SockaContractBound>(contract: TContract, sessionRef: RefObject<SockaSession<TContract> | null>): InferSockaSend<TContract>;
/**
 * ```tsx
 * const { ready, send } = useSockaSession(myContract, { url }, deps);
 * await send.echo({ message: "hi" });
 * ```
 */
declare function useSockaSession<TContract extends SockaContractBound>(contract: TContract, options: UseSockaSessionOptions<TContract>, deps: DependencyList): {
    ready: boolean;
    send: InferSockaSend<TContract>;
    sessionRef: RefObject<SockaSession<TContract> | null>;
    status: SockaConnectionStatus;
    reconnecting: boolean;
    reconnectAttempt: number;
};

type SockaPresenceOptions<TContract extends SockaContractBound, TUser extends {
    userId: string;
}, KJoin extends keyof TContract["pushes"] & string, KLeave extends keyof TContract["pushes"] & string> = {
    snapshot: () => Promise<{
        selfUserId: string;
        users: TUser[];
    }>;
    joinPush: KJoin;
    leavePush: KLeave;
    mapJoinUser: (p: InferSockaPushPayload<TContract, KJoin>) => TUser;
    mapLeaveUserId: (p: InferSockaPushPayload<TContract, KLeave>) => string;
    /** Optional display order after each update (e.g. by `displayName`). */
    sortUsers?: (a: TUser, b: TUser) => number;
};
/**
 * Loads a presence snapshot RPC once, then merges **`joinPush`** / **`leavePush`** deltas.
 * Pass the same **`deps`** you use for {@link useSocka} when room identity changes.
 * Options are read from a ref so you do not need to memoize the **`options`** object.
 */
declare function useSockaPresence<TContract extends SockaContractBound, TUser extends {
    userId: string;
}, KJoin extends keyof TContract["pushes"] & string, KLeave extends keyof TContract["pushes"] & string>(sessionRef: RefObject<SockaSession<TContract> | null>, ready: boolean, options: SockaPresenceOptions<TContract, TUser, KJoin, KLeave>, deps: DependencyList): {
    users: TUser[];
    selfUserId: string | undefined;
    loading: boolean;
};

type AnySockaContract = SockaContractBound;
/**
 * Session slice stored on React context by {@link SockaSessionProvider}. The typed
 * `send` object is built in {@link useSockaSessionContext} (same as {@link useSockaSession})
 * so children do not open duplicate WebSockets.
 */
type SockaSessionContextValue<TContract extends SockaContractBound = AnySockaContract> = {
    readonly contract: TContract;
    readonly ready: boolean;
    readonly sessionRef: RefObject<SockaSession<TContract> | null>;
    readonly status: SockaConnectionStatus;
    readonly reconnecting: boolean;
    readonly reconnectAttempt: number;
};
type SockaSessionProviderProps<TContract extends SockaContractBound> = {
    readonly contract: TContract;
    readonly deps: DependencyList;
    readonly children: ReactNode;
} & UseSockaSessionOptions<TContract>;
/**
 * Owns a single {@link SockaSession} / WebSocket and exposes it to descendants via
 * {@link useSockaSessionContext}. Mount once per connection (e.g. layout); avoid
 * calling {@link useSockaSession} in every leaf—use the context hook instead.
 */
declare function SockaSessionProvider<TContract extends SockaContractBound>(props: SockaSessionProviderProps<TContract>): ReactElement;
declare namespace SockaSessionProvider {
    var displayName: string;
}
/**
 * Reads the socka session from the nearest {@link SockaSessionProvider}.
 * Pass the **same** `contract` reference as the provider for typing and validation.
 */
declare function useSockaSessionContext<TContract extends SockaContractBound>(contract: TContract): {
    ready: boolean;
    send: InferSockaSend<TContract>;
    sessionRef: RefObject<SockaSession<TContract> | null>;
    status: SockaConnectionStatus;
    reconnecting: boolean;
    reconnectAttempt: number;
};

export { type SockaPresenceOptions, type SockaSessionContextValue, SockaSessionProvider, type SockaSessionProviderProps, type UseSockaOptions, type UseSockaSessionOptions, createSockaSendProxyFromSession, useSocka, useSockaPresence, useSockaSession, useSockaSessionContext };
