import { Result } from "../result-_socO0Ud.js";
import "../tap-err-C0xfVXtz.js";
import "../index-D0f5JWiT.js";
import { DefaultError, MutationKey, MutationObserverOptions, QueryClient, QueryFunction, QueryKey, QueryObserverOptions } from "@tanstack/query-core";

//#region src/query/utils.d.ts

/**
 * Input for `resultQueryOptions` and `defineQuery`.
 *
 * Mirrors TanStack Query's `QueryObserverOptions` but expects `queryFn` to
 * return a Wellcrafted `Result`. The Result is unwrapped into TanStack's
 * throwing data/error contract by `resultQueryOptions`.
 *
 * @template TQueryFnData - The success type produced by `queryFn`
 * @template TError - The error type carried by the Result
 * @template TData - The type seen by consumers after `select`
 * @template TQueryData - The type stored in the cache (usually `TQueryFnData`)
 * @template TQueryKey - The literal query key tuple
 */
type QueryOptionsInput<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> = Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>, "queryFn"> & {
  queryKey: TQueryKey;
  queryFn: QueryFunction<Result<TQueryFnData, TError>, TQueryKey>;
};
/**
 * Input for `resultMutationOptions` and `defineMutation`.
 *
 * Mirrors TanStack Query's `MutationObserverOptions` but expects `mutationFn`
 * to return a Wellcrafted `Result`. The Result is unwrapped into TanStack's
 * throwing data/error contract by `resultMutationOptions`.
 *
 * @template TData - The success type produced by `mutationFn`
 * @template TError - The error type carried by the Result
 * @template TVariables - The variables passed to `mutationFn`
 * @template TContext - The context type for optimistic updates
 * @template TMutationKey - The literal mutation key tuple
 */
type MutationOptionsInput<TData, TError, TVariables = void, TContext = unknown, TMutationKey extends MutationKey = MutationKey> = Omit<MutationObserverOptions<TData, TError, TVariables, TContext>, "mutationFn"> & {
  mutationKey: TMutationKey;
  mutationFn: (variables: TVariables) => Result<TData, TError> | Promise<Result<TData, TError>>;
};
/**
 * Adapter from a Result-returning query function to TanStack Query options.
 *
 * This is the single canonical place where `Result<TQueryFnData, TError>`
 * is converted into TanStack's contract: `Ok(data)` resolves with `data`,
 * `Err(error)` throws `error` into the query error channel.
 *
 * Use this directly with framework hooks when you do not need the
 * `QueryClient`-bound imperative helpers from `defineQuery`:
 *
 * ```ts
 * const query = createQuery(() => resultQueryOptions({
 *   queryKey: ['user', userId],
 *   queryFn: () => services.getUser(userId),
 * }));
 * ```
 *
 * `defineQuery` composes through this helper, so the `.options` it returns
 * is the same shape `resultQueryOptions` produces.
 *
 * @param input - Result-aware query configuration
 * @returns TanStack Query `QueryObserverOptions` with `queryFn` rewired to
 *   resolve `Ok` and throw `Err`
 */
declare function resultQueryOptions<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData, const TQueryKey extends QueryKey = QueryKey>(input: QueryOptionsInput<TQueryFnData, TError, TData, TQueryData, TQueryKey>): QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>;
/**
 * Adapter from a Result-returning mutation function to TanStack Query options.
 *
 * This is the single canonical place where `Result<TData, TError>` is
 * converted into TanStack's contract: `Ok(data)` resolves with `data`,
 * `Err(error)` throws `error` into the mutation error channel.
 *
 * Use this directly with framework hooks when you do not need the
 * `QueryClient`-bound imperative helpers from `defineMutation`:
 *
 * ```ts
 * const save = createMutation(() => resultMutationOptions({
 *   mutationKey: ['saveUser'],
 *   mutationFn: (input: SaveUserInput) => services.saveUser(input),
 * }));
 * ```
 *
 * `defineMutation` composes through this helper, so the `.options` it
 * returns is the same shape `resultMutationOptions` produces.
 *
 * @param input - Result-aware mutation configuration
 * @returns TanStack Query `MutationObserverOptions` with `mutationFn` rewired
 *   to resolve `Ok` and throw `Err`
 */
declare function resultMutationOptions<TData, TError, TVariables = void, TContext = unknown, const TMutationKey extends MutationKey = MutationKey>(input: MutationOptionsInput<TData, TError, TVariables, TContext, TMutationKey>): MutationObserverOptions<TData, TError, TVariables, TContext>;
/**
 * Output of `defineQuery`.
 *
 * Query imperative reads require an explicit cache policy.
 *
 * - `options`: Options shape produced by `resultQueryOptions`, ready for hooks.
 * - `fetch()`: Always evaluates freshness; refetches if stale.
 * - `ensure()`: Prefers cached data; fetches only when missing.
 */
type DefineQueryOutput<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> = {
  options: QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>;
  fetch: () => Promise<Result<TQueryData, TError>>;
  ensure: () => Promise<Result<TQueryData, TError>>;
};
/**
 * Output of `defineMutation`.
 *
 * The returned function directly executes the mutation.
 *
 * - `(variables)` (callable): Imperatively runs the mutation, returning a Result.
 * - `options`: Options shape produced by `resultMutationOptions`, ready for hooks.
 */
type DefineMutationOutput<TData, TError, TVariables = void, TContext = unknown> = ((variables: TVariables) => Promise<Result<TData, TError>>) & {
  options: MutationObserverOptions<TData, TError, TVariables, TContext>;
};
/**
 * Creates `defineQuery` and `defineMutation` bound to a specific `QueryClient`.
 *
 * Use this when you want a reusable query/mutation definition that carries
 * its own imperative query helpers (`.fetch`, `.ensure`) and callable mutation
 * execution powered by a specific client. For local one-shot options that only need
 * to flow into a framework hook, prefer `resultQueryOptions` / `resultMutationOptions`
 * directly: those are platform-agnostic and do not require a `QueryClient`.
 *
 * Both `defineQuery` and `defineMutation` compose through `resultQueryOptions` and
 * `resultMutationOptions`, so there is exactly one place that unwraps `Result`
 * into TanStack's throwing contract.
 *
 * @param queryClient - The TanStack `QueryClient` to bind imperative helpers to
 *
 * @example
 * ```ts
 * const queryClient = new QueryClient();
 * const { defineQuery, defineMutation } = createQueryFactories(queryClient);
 *
 * const userQuery = defineQuery({
 *   queryKey: ['user', userId],
 *   queryFn: () => services.getUser(userId),
 * });
 *
 * // Reactive
 * const query = createQuery(() => userQuery.options);
 *
 * // Imperative
 * const { data, error } = await userQuery.fetch();
 * ```
 */
declare function createQueryFactories(queryClient: QueryClient): {
  defineQuery: <TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, const TQueryKey extends QueryKey = readonly unknown[]>(input: QueryOptionsInput<TQueryFnData, TError, TData, TQueryData, TQueryKey>) => DefineQueryOutput<TQueryFnData, TError, TData, TQueryData, TQueryKey>;
  defineMutation: <TData, TError, TVariables = void, TContext = unknown, const TMutationKey extends MutationKey = readonly unknown[]>(input: MutationOptionsInput<TData, TError, TVariables, TContext, TMutationKey>) => DefineMutationOutput<TData, TError, TVariables, TContext>;
};
/**
 * Identity helper for declaring a TanStack Query key map while preserving
 * tuple types.
 *
 * - **Static entries** like `['users', 'active']` are narrowed to readonly
 *   tuples with full literal precision (e.g. `readonly ['users', 'active']`)
 *   via the `const` type parameter modifier. No per-line `as const` needed.
 *
 * - **Factory entries** like `(id: string) => ['users', id]` are narrowed to
 *   tuple SHAPE (e.g. `[string, string]` with correct arity), not widened to
 *   `string[]`. This happens because the strict tuple constraint provides
 *   contextual typing into the function body. Literal positions still widen
 *   without `as const` (TS does not propagate literal narrowing through
 *   contextual typing). Add `as const` to the body when you need the literal:
 *   `(id) => ['users', id] as const` -> `readonly ['users', string]`.
 *
 * Empty arrays and non-key values are rejected at the type level.
 *
 * @example
 * ```ts
 * const userKeys = defineKeys({
 *   all: ['users'],                          // readonly ['users']
 *   active: ['users', 'active'],             // readonly ['users', 'active']
 *   detail: (id: string) => ['users', id],   // [string, string] (tuple shape kept)
 *   page: (n: number) => ['users', n] as const, // readonly ['users', number]
 * });
 * ```
 */
declare function defineKeys<const TKeys extends Record<string, readonly [unknown, ...unknown[]] | ((...args: never[]) => readonly [unknown, ...unknown[]])>>(keys: TKeys): TKeys;
//#endregion
export { createQueryFactories, defineKeys, resultMutationOptions, resultQueryOptions };
//# sourceMappingURL=index.d.ts.map