// src/query/react/index.ts
import { coreModule, buildCreateApi } from "@reduxjs/toolkit/query";

// src/query/react/buildHooks.ts
import { createSelector } from "@reduxjs/toolkit";
import {
  useCallback,
  useDebugValue,
  useEffect as useEffect3,
  useLayoutEffect,
  useMemo as useMemo2,
  useRef as useRef3,
  useState
} from "react";
import { QueryStatus, skipToken } from "@reduxjs/toolkit/query";
import { shallowEqual as shallowEqual2 } from "react-redux";

// src/query/react/useSerializedStableValue.ts
import { useEffect, useRef, useMemo } from "react";
function useStableQueryArgs(queryArgs, serialize, endpointDefinition, endpointName) {
  const incoming = useMemo(
    () => ({
      queryArgs,
      serialized: typeof queryArgs == "object" ? serialize({ queryArgs, endpointDefinition, endpointName }) : queryArgs
    }),
    [queryArgs, serialize, endpointDefinition, endpointName]
  );
  const cache2 = useRef(incoming);
  useEffect(() => {
    if (cache2.current.serialized !== incoming.serialized) {
      cache2.current = incoming;
    }
  }, [incoming]);
  return cache2.current.serialized === incoming.serialized ? cache2.current.queryArgs : queryArgs;
}

// src/query/react/constants.ts
var UNINITIALIZED_VALUE = Symbol();

// src/query/react/useShallowStableValue.ts
import { useEffect as useEffect2, useRef as useRef2 } from "react";
import { shallowEqual } from "react-redux";
function useShallowStableValue(value) {
  const cache2 = useRef2(value);
  useEffect2(() => {
    if (!shallowEqual(cache2.current, value)) {
      cache2.current = value;
    }
  }, [value]);
  return shallowEqual(cache2.current, value) ? cache2.current : value;
}

// src/query/defaultSerializeQueryArgs.ts
import { isPlainObject } from "@reduxjs/toolkit";
var cache = WeakMap ? /* @__PURE__ */ new WeakMap() : void 0;
var defaultSerializeQueryArgs = ({
  endpointName,
  queryArgs
}) => {
  let serialized = "";
  const cached = cache?.get(queryArgs);
  if (typeof cached === "string") {
    serialized = cached;
  } else {
    const stringified = JSON.stringify(
      queryArgs,
      (key, value) => isPlainObject(value) ? Object.keys(value).sort().reduce((acc, key2) => {
        acc[key2] = value[key2];
        return acc;
      }, {}) : value
    );
    if (isPlainObject(queryArgs)) {
      cache?.set(queryArgs, stringified);
    }
    serialized = stringified;
  }
  return `${endpointName}(${serialized})`;
};

// src/query/react/buildHooks.ts
var useIsomorphicLayoutEffect = typeof window !== "undefined" && !!window.document && !!window.document.createElement ? useLayoutEffect : useEffect3;
var defaultMutationStateSelector = (x) => x;
var noPendingQueryStateSelector = (selected) => {
  if (selected.isUninitialized) {
    return {
      ...selected,
      isUninitialized: false,
      isFetching: true,
      isLoading: selected.data !== void 0 ? false : true,
      status: QueryStatus.pending
    };
  }
  return selected;
};
function buildHooks({
  api,
  moduleOptions: {
    batch,
    hooks: { useDispatch, useSelector, useStore },
    unstable__sideEffectsInRender
  },
  serializeQueryArgs,
  context
}) {
  const usePossiblyImmediateEffect = unstable__sideEffectsInRender ? (cb) => cb() : useEffect3;
  return { buildQueryHooks, buildMutationHook, usePrefetch };
  function queryStatePreSelector(currentState, lastResult, queryArgs) {
    if (lastResult?.endpointName && currentState.isUninitialized) {
      const { endpointName } = lastResult;
      const endpointDefinition = context.endpointDefinitions[endpointName];
      if (serializeQueryArgs({
        queryArgs: lastResult.originalArgs,
        endpointDefinition,
        endpointName
      }) === serializeQueryArgs({
        queryArgs,
        endpointDefinition,
        endpointName
      }))
        lastResult = void 0;
    }
    let data = currentState.isSuccess ? currentState.data : lastResult?.data;
    if (data === void 0)
      data = currentState.data;
    const hasData = data !== void 0;
    const isFetching = currentState.isLoading;
    const isLoading = !hasData && isFetching;
    const isSuccess = currentState.isSuccess || isFetching && hasData;
    return {
      ...currentState,
      data,
      currentData: currentState.data,
      isFetching,
      isLoading,
      isSuccess
    };
  }
  function usePrefetch(endpointName, defaultOptions) {
    const dispatch = useDispatch();
    const stableDefaultOptions = useShallowStableValue(defaultOptions);
    return useCallback(
      (arg, options) => dispatch(
        api.util.prefetch(endpointName, arg, {
          ...stableDefaultOptions,
          ...options
        })
      ),
      [endpointName, dispatch, stableDefaultOptions]
    );
  }
  function buildQueryHooks(name) {
    const useQuerySubscription = (arg, {
      refetchOnReconnect,
      refetchOnFocus,
      refetchOnMountOrArgChange,
      skip = false,
      pollingInterval = 0
    } = {}) => {
      const { initiate } = api.endpoints[name];
      const dispatch = useDispatch();
      const stableArg = useStableQueryArgs(
        skip ? skipToken : arg,
        // Even if the user provided a per-endpoint `serializeQueryArgs` with
        // a consistent return value, _here_ we want to use the default behavior
        // so we can tell if _anything_ actually changed. Otherwise, we can end up
        // with a case where the query args did change but the serialization doesn't,
        // and then we never try to initiate a refetch.
        defaultSerializeQueryArgs,
        context.endpointDefinitions[name],
        name
      );
      const stableSubscriptionOptions = useShallowStableValue({
        refetchOnReconnect,
        refetchOnFocus,
        pollingInterval
      });
      const lastRenderHadSubscription = useRef3(false);
      const promiseRef = useRef3();
      let { queryCacheKey, requestId } = promiseRef.current || {};
      let currentRenderHasSubscription = false;
      if (queryCacheKey && requestId) {
        const returnedValue = dispatch(
          api.internalActions.internal_probeSubscription({
            queryCacheKey,
            requestId
          })
        );
        if (process.env.NODE_ENV !== "production") {
          if (typeof returnedValue !== "boolean") {
            throw new Error(
              `Warning: Middleware for RTK-Query API at reducerPath "${api.reducerPath}" has not been added to the store.
    You must add the middleware for RTK-Query to function correctly!`
            );
          }
        }
        currentRenderHasSubscription = !!returnedValue;
      }
      const subscriptionRemoved = !currentRenderHasSubscription && lastRenderHadSubscription.current;
      usePossiblyImmediateEffect(() => {
        lastRenderHadSubscription.current = currentRenderHasSubscription;
      });
      usePossiblyImmediateEffect(() => {
        if (subscriptionRemoved) {
          promiseRef.current = void 0;
        }
      }, [subscriptionRemoved]);
      usePossiblyImmediateEffect(() => {
        const lastPromise = promiseRef.current;
        if (typeof process !== "undefined" && process.env.NODE_ENV === "removeMeOnCompilation") {
          console.log(subscriptionRemoved);
        }
        if (stableArg === skipToken) {
          lastPromise?.unsubscribe();
          promiseRef.current = void 0;
          return;
        }
        const lastSubscriptionOptions = promiseRef.current?.subscriptionOptions;
        if (!lastPromise || lastPromise.arg !== stableArg) {
          lastPromise?.unsubscribe();
          const promise = dispatch(
            initiate(stableArg, {
              subscriptionOptions: stableSubscriptionOptions,
              forceRefetch: refetchOnMountOrArgChange
            })
          );
          promiseRef.current = promise;
        } else if (stableSubscriptionOptions !== lastSubscriptionOptions) {
          lastPromise.updateSubscriptionOptions(stableSubscriptionOptions);
        }
      }, [
        dispatch,
        initiate,
        refetchOnMountOrArgChange,
        stableArg,
        stableSubscriptionOptions,
        subscriptionRemoved
      ]);
      useEffect3(() => {
        return () => {
          promiseRef.current?.unsubscribe();
          promiseRef.current = void 0;
        };
      }, []);
      return useMemo2(
        () => ({
          /**
           * A method to manually refetch data for the query
           */
          refetch: () => {
            if (!promiseRef.current)
              throw new Error(
                "Cannot refetch a query that has not been started yet."
              );
            return promiseRef.current?.refetch();
          }
        }),
        []
      );
    };
    const useLazyQuerySubscription = ({
      refetchOnReconnect,
      refetchOnFocus,
      pollingInterval = 0
    } = {}) => {
      const { initiate } = api.endpoints[name];
      const dispatch = useDispatch();
      const [arg, setArg] = useState(UNINITIALIZED_VALUE);
      const promiseRef = useRef3();
      const stableSubscriptionOptions = useShallowStableValue({
        refetchOnReconnect,
        refetchOnFocus,
        pollingInterval
      });
      usePossiblyImmediateEffect(() => {
        const lastSubscriptionOptions = promiseRef.current?.subscriptionOptions;
        if (stableSubscriptionOptions !== lastSubscriptionOptions) {
          promiseRef.current?.updateSubscriptionOptions(
            stableSubscriptionOptions
          );
        }
      }, [stableSubscriptionOptions]);
      const subscriptionOptionsRef = useRef3(stableSubscriptionOptions);
      usePossiblyImmediateEffect(() => {
        subscriptionOptionsRef.current = stableSubscriptionOptions;
      }, [stableSubscriptionOptions]);
      const trigger = useCallback(
        function(arg2, preferCacheValue = false) {
          let promise;
          batch(() => {
            promiseRef.current?.unsubscribe();
            promiseRef.current = promise = dispatch(
              initiate(arg2, {
                subscriptionOptions: subscriptionOptionsRef.current,
                forceRefetch: !preferCacheValue
              })
            );
            setArg(arg2);
          });
          return promise;
        },
        [dispatch, initiate]
      );
      useEffect3(() => {
        return () => {
          promiseRef?.current?.unsubscribe();
        };
      }, []);
      useEffect3(() => {
        if (arg !== UNINITIALIZED_VALUE && !promiseRef.current) {
          trigger(arg, true);
        }
      }, [arg, trigger]);
      return useMemo2(() => [trigger, arg], [trigger, arg]);
    };
    const useQueryState = (arg, { skip = false, selectFromResult } = {}) => {
      const { select } = api.endpoints[name];
      const stableArg = useStableQueryArgs(
        skip ? skipToken : arg,
        serializeQueryArgs,
        context.endpointDefinitions[name],
        name
      );
      const lastValue = useRef3();
      const selectDefaultResult = useMemo2(
        () => createSelector(
          [
            select(stableArg),
            (_, lastResult) => lastResult,
            (_) => stableArg
          ],
          queryStatePreSelector
        ),
        [select, stableArg]
      );
      const querySelector = useMemo2(
        () => selectFromResult ? createSelector([selectDefaultResult], selectFromResult) : selectDefaultResult,
        [selectDefaultResult, selectFromResult]
      );
      const currentState = useSelector(
        (state) => querySelector(state, lastValue.current),
        shallowEqual2
      );
      const store = useStore();
      const newLastValue = selectDefaultResult(
        store.getState(),
        lastValue.current
      );
      useIsomorphicLayoutEffect(() => {
        lastValue.current = newLastValue;
      }, [newLastValue]);
      return currentState;
    };
    return {
      useQueryState,
      useQuerySubscription,
      useLazyQuerySubscription,
      useLazyQuery(options) {
        const [trigger, arg] = useLazyQuerySubscription(options);
        const queryStateResults = useQueryState(arg, {
          ...options,
          skip: arg === UNINITIALIZED_VALUE
        });
        const info = useMemo2(() => ({ lastArg: arg }), [arg]);
        return useMemo2(
          () => [trigger, queryStateResults, info],
          [trigger, queryStateResults, info]
        );
      },
      useQuery(arg, options) {
        const querySubscriptionResults = useQuerySubscription(arg, options);
        const queryStateResults = useQueryState(arg, {
          selectFromResult: arg === skipToken || options?.skip ? void 0 : noPendingQueryStateSelector,
          ...options
        });
        const { data, status, isLoading, isSuccess, isError, error } = queryStateResults;
        useDebugValue({ data, status, isLoading, isSuccess, isError, error });
        return useMemo2(
          () => ({ ...queryStateResults, ...querySubscriptionResults }),
          [queryStateResults, querySubscriptionResults]
        );
      }
    };
  }
  function buildMutationHook(name) {
    return ({
      selectFromResult = defaultMutationStateSelector,
      fixedCacheKey
    } = {}) => {
      const { select, initiate } = api.endpoints[name];
      const dispatch = useDispatch();
      const [promise, setPromise] = useState();
      useEffect3(
        () => () => {
          if (!promise?.arg.fixedCacheKey) {
            promise?.reset();
          }
        },
        [promise]
      );
      const triggerMutation = useCallback(
        function(arg) {
          const promise2 = dispatch(initiate(arg, { fixedCacheKey }));
          setPromise(promise2);
          return promise2;
        },
        [dispatch, initiate, fixedCacheKey]
      );
      const { requestId } = promise || {};
      const mutationSelector = useMemo2(
        () => createSelector(
          [select({ fixedCacheKey, requestId: promise?.requestId })],
          selectFromResult
        ),
        [select, promise, selectFromResult, fixedCacheKey]
      );
      const currentState = useSelector(mutationSelector, shallowEqual2);
      const originalArgs = fixedCacheKey == null ? promise?.arg.originalArgs : void 0;
      const reset = useCallback(() => {
        batch(() => {
          if (promise) {
            setPromise(void 0);
          }
          if (fixedCacheKey) {
            dispatch(
              api.internalActions.removeMutationResult({
                requestId,
                fixedCacheKey
              })
            );
          }
        });
      }, [dispatch, fixedCacheKey, promise, requestId]);
      const {
        endpointName,
        data,
        status,
        isLoading,
        isSuccess,
        isError,
        error
      } = currentState;
      useDebugValue({
        endpointName,
        data,
        status,
        isLoading,
        isSuccess,
        isError,
        error
      });
      const finalState = useMemo2(
        () => ({ ...currentState, originalArgs, reset }),
        [currentState, originalArgs, reset]
      );
      return useMemo2(
        () => [triggerMutation, finalState],
        [triggerMutation, finalState]
      );
    };
  }
}

// src/query/endpointDefinitions.ts
function isQueryDefinition(e) {
  return e.type === "query" /* query */;
}
function isMutationDefinition(e) {
  return e.type === "mutation" /* mutation */;
}

// src/query/utils/capitalize.ts
function capitalize(str) {
  return str.replace(str[0], str[0].toUpperCase());
}

// src/query/tsHelpers.ts
function safeAssign(target, ...args) {
  return Object.assign(target, ...args);
}

// src/query/react/module.ts
import {
  useDispatch as rrUseDispatch,
  useSelector as rrUseSelector,
  useStore as rrUseStore,
  batch as rrBatch
} from "react-redux";
var reactHooksModuleName = /* @__PURE__ */ Symbol();
var reactHooksModule = ({
  batch = rrBatch,
  hooks = {
    useDispatch: rrUseDispatch,
    useSelector: rrUseSelector,
    useStore: rrUseStore
  },
  unstable__sideEffectsInRender = false
} = {}) => ({
  name: reactHooksModuleName,
  init(api, { serializeQueryArgs }, context) {
    const anyApi = api;
    const { buildQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
      api,
      moduleOptions: {
        batch,
        hooks,
        unstable__sideEffectsInRender
      },
      serializeQueryArgs,
      context
    });
    safeAssign(anyApi, { usePrefetch });
    safeAssign(context, { batch });
    return {
      injectEndpoint(endpointName, definition) {
        if (isQueryDefinition(definition)) {
          const {
            useQuery,
            useLazyQuery,
            useLazyQuerySubscription,
            useQueryState,
            useQuerySubscription
          } = buildQueryHooks(endpointName);
          safeAssign(anyApi.endpoints[endpointName], {
            useQuery,
            useLazyQuery,
            useLazyQuerySubscription,
            useQueryState,
            useQuerySubscription
          });
          api[`use${capitalize(endpointName)}Query`] = useQuery;
          api[`useLazy${capitalize(endpointName)}Query`] = useLazyQuery;
        } else if (isMutationDefinition(definition)) {
          const useMutation = buildMutationHook(endpointName);
          safeAssign(anyApi.endpoints[endpointName], {
            useMutation
          });
          api[`use${capitalize(endpointName)}Mutation`] = useMutation;
        }
      }
    };
  }
});

// src/query/react/index.ts
export * from "@reduxjs/toolkit/query";

// src/query/react/ApiProvider.tsx
import { configureStore } from "@reduxjs/toolkit";
import { useEffect as useEffect4 } from "react";
import React from "react";
import { Provider } from "react-redux";
import { setupListeners } from "@reduxjs/toolkit/query";
function ApiProvider(props) {
  const [store] = React.useState(
    () => configureStore({
      reducer: {
        [props.api.reducerPath]: props.api.reducer
      },
      middleware: (gDM) => gDM().concat(props.api.middleware)
    })
  );
  useEffect4(
    () => props.setupListeners === false ? void 0 : setupListeners(store.dispatch, props.setupListeners),
    [props.setupListeners, store.dispatch]
  );
  return /* @__PURE__ */ React.createElement(Provider, { store, context: props.context }, props.children);
}

// src/query/react/index.ts
var createApi = /* @__PURE__ */ buildCreateApi(
  coreModule(),
  reactHooksModule()
);
export {
  ApiProvider,
  createApi,
  reactHooksModule
};
//# sourceMappingURL=rtk-query-react.modern.mjs.map