ngrx-rtk-query
Version:
Angular RTK Query
712 lines (697 loc) • 32.5 kB
JavaScript
import { computed, signal, effect, untracked, isDevMode, inject, DestroyRef, runInInjectionContext } from '@angular/core';
import { QueryStatus, skipToken, defaultSerializeQueryArgs, fetchBaseQuery as fetchBaseQuery$1, buildCreateApi, coreModule } from '@reduxjs/toolkit/query';
export * from '@reduxjs/toolkit/query';
const UNINITIALIZED_VALUE = Symbol();
var DefinitionType;
(function (DefinitionType) {
DefinitionType["query"] = "query";
DefinitionType["mutation"] = "mutation";
DefinitionType["infinitequery"] = "infinitequery";
})(DefinitionType || (DefinitionType = {}));
function isQueryDefinition(e) {
return e.type === DefinitionType.query;
}
function isMutationDefinition(e) {
return e.type === DefinitionType.mutation;
}
function isInfiniteQueryDefinition(e) {
return e.type === DefinitionType.infinitequery;
}
function useStableQueryArgs(queryArgs, serialize, endpointDefinition, endpointName) {
const incoming = computed(() => {
const incomingArgs = queryArgs();
return {
queryArgs: incomingArgs,
serialized: typeof incomingArgs == 'object'
? serialize({ queryArgs: incomingArgs, endpointDefinition, endpointName })
: incomingArgs,
};
}, { equal: (a, b) => a.serialized === b.serialized });
return computed(() => incoming().queryArgs);
}
function capitalize(str) {
return str.replace(str[0], str[0].toUpperCase());
}
function toLazySignal(inputSignal, { initialValue }) {
const s = signal(initialValue);
effect(() => {
const input = inputSignal();
untracked(() => s.set(input));
});
return s.asReadonly();
}
function is(x, y) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y;
}
else {
return x !== x && y !== y;
}
}
function shallowEqual(objA, objB) {
if (is(objA, objB)) {
return true;
}
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < keysA.length; i++) {
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}
/**
* The code in this file is adapted from TanStack/query
*
* TanStack/query is an open-source project licensed under the MIT license.
*
* For more information about the original code, see
* https://github.com/TanStack/query
*/
/**
* Exposes fields of an object passed via an Angular `Signal` as `Computed` signals.
*
* Functions on the object are passed through as-is.
*
* @param signal - `Signal` that must return an object.
*
*/
function signalProxy(signal) {
const internalState = {};
return new Proxy(internalState, {
get(target, prop) {
// first check if we have it in our internal state and return it
const computedField = target[prop];
if (computedField)
return computedField;
// then, check if it's a function on the resultState and return it
const targetField = untracked(signal)[prop];
if (typeof targetField === 'function')
return targetField;
// finally, create a computed field, store it and return it
// @ts-expect-error bypass
return (target[prop] = computed(() => signal()[prop]));
},
has(_, prop) {
return !!untracked(signal)[prop];
},
ownKeys() {
return Reflect.ownKeys(untracked(signal));
},
getOwnPropertyDescriptor() {
return {
enumerable: true,
configurable: true,
};
},
});
}
function toDeepSignal(signal) {
const deepSignal = signalProxy(signal);
return Object.assign(signal, deepSignal);
}
function safeAssign(target, ...args) {
return Object.assign(target, ...args);
}
/**
* Wrapper around `defaultQueryStateSelector` to be used in `useQuery`.
* We want the initial render to already come back with
* `{ isUninitialized: false, isFetching: true, isLoading: true }`
* to prevent that the library user has to do an additional check for `isUninitialized`/
*/
const noPendingQueryStateSelector = (selected) => {
if (selected.isUninitialized) {
return {
...selected,
isUninitialized: false,
isFetching: true,
isLoading: selected.data !== undefined ? false : true,
status: QueryStatus.pending,
};
}
return selected;
};
/**
*
* @param opts.api - An API with defined endpoints to create hooks for
* @param opts.moduleOptions.dispatch - The version of the `dispatch` to be used
* @param opts.moduleOptions.useSelector - The version of the `useSelector` hook to be used
* @param opts.moduleOptions.getState - The version of the `getState` to be used
* @returns An object containing functions to generate hooks based on an endpoint
*/
function buildHooks({ api, moduleOptions: { hooks: { dispatch, useSelector, getState }, createSelector, }, serializeQueryArgs, context, }) {
return { buildQueryHooks, buildInfiniteQueryHooks, buildMutationHook, usePrefetch };
function queryStatePreSelector(currentState, lastResult, queryArgs) {
// if we had a last result and the current result is uninitialized,
// we might have called `api.util.resetApiState`
// in this case, reset the hook
if (lastResult?.endpointName && currentState.isUninitialized) {
const { endpointName } = lastResult;
const endpointDefinition = context.endpointDefinitions[endpointName];
if (queryArgs !== skipToken &&
serializeQueryArgs({
queryArgs: lastResult.originalArgs,
endpointDefinition,
endpointName,
}) ===
serializeQueryArgs({
queryArgs,
endpointDefinition,
endpointName,
}))
lastResult = undefined;
}
// data is the last known good request result we have tracked
// or if none has been tracked yet the last good result for the current args
let data = currentState.isSuccess ? currentState.data : lastResult?.data;
if (data === undefined)
data = currentState.data;
const hasData = data !== undefined;
// isFetching = true any time a request is in flight
const isFetching = currentState.isLoading;
// isLoading = true only when loading while no data is present yet (initial load with no data in the cache)
const isLoading = (!lastResult || lastResult.isLoading || lastResult.isUninitialized) && !hasData && isFetching;
// isSuccess = true when data is present and we're not refetching after an error.
// That includes cases where the _current_ item is either actively
// fetching or about to fetch due to an uninitialized entry.
const isSuccess = currentState.isSuccess || (hasData && ((isFetching && !lastResult?.isError) || currentState.isUninitialized));
return {
...currentState,
data,
currentData: currentState.data,
isFetching,
isLoading,
isSuccess,
// Deep signals required init properties undefined atleast
endpointName: currentState.endpointName,
error: currentState.error,
fulfilledTimeStamp: currentState.fulfilledTimeStamp,
originalArgs: currentState.originalArgs,
requestId: currentState.requestId,
startedTimeStamp: currentState.startedTimeStamp,
};
}
function infiniteQueryStatePreSelector(currentState, lastResult, queryArgs) {
// if we had a last result and the current result is uninitialized,
// we might have called `api.util.resetApiState`
// in this case, reset the hook
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 = undefined;
}
// data is the last known good request result we have tracked - or if none has been tracked yet the last good result for the current args
let data = currentState.isSuccess ? currentState.data : lastResult?.data;
if (data === undefined)
data = currentState.data;
const hasData = data !== undefined;
// isFetching = true any time a request is in flight
const isFetching = currentState.isLoading;
// isLoading = true only when loading while no data is present yet (initial load with no data in the cache)
const isLoading = (!lastResult || lastResult.isLoading || lastResult.isUninitialized) && !hasData && isFetching;
// isSuccess = true when data is present
const isSuccess = currentState.isSuccess || (isFetching && hasData);
return {
...currentState,
data,
currentData: currentState.data,
isFetching,
isLoading,
isSuccess,
// Deep signals required init properties undefined atleast
endpointName: currentState.endpointName,
error: currentState.error,
fulfilledTimeStamp: currentState.fulfilledTimeStamp,
originalArgs: currentState.originalArgs,
requestId: currentState.requestId,
startedTimeStamp: currentState.startedTimeStamp,
};
}
function usePrefetch(endpointName, defaultOptions) {
return (arg, options) => dispatch(api.util.prefetch(endpointName, arg, { ...defaultOptions, ...options }));
}
function useQuerySubscriptionCommonImpl(endpointName, arg, options = {}) {
const { initiate } = api.endpoints[endpointName];
const subscriptionOptions = computed(() => {
const { refetchOnReconnect, refetchOnFocus, refetchOnMountOrArgChange, skip = false, pollingInterval = 0, skipPollingIfUnfocused = false, ...rest } = typeof options === 'function' ? options() : options;
return {
refetchOnReconnect,
refetchOnFocus,
refetchOnMountOrArgChange,
skip,
pollingInterval,
skipPollingIfUnfocused,
...rest,
};
});
const subscriptionArg = computed(() => {
const subscriptionArg = typeof arg === 'function' ? arg() : arg;
return subscriptionOptions().skip ? skipToken : subscriptionArg;
});
let subscriptionSelectorsRef;
if (!subscriptionSelectorsRef) {
const returnedValue = dispatch(api.internalActions.internal_getRTKQSubscriptions());
if (isDevMode()) {
if (typeof returnedValue !== 'object' || typeof returnedValue?.type === 'string') {
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!`);
}
}
subscriptionSelectorsRef = returnedValue;
}
const stableArg = useStableQueryArgs(subscriptionArg,
// 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[endpointName], endpointName);
const stableSubscriptionOptions = computed(() => {
const { refetchOnReconnect, refetchOnFocus, pollingInterval, skipPollingIfUnfocused } = subscriptionOptions();
return { refetchOnReconnect, refetchOnFocus, pollingInterval, skipPollingIfUnfocused };
}, { equal: shallowEqual });
let lastRenderHadSubscription = false;
const promiseRef = { current: undefined };
const forceRefetch = computed(() => subscriptionOptions().refetchOnMountOrArgChange);
const initialPageParam = computed(() => subscriptionOptions().initialPageParam);
effect(() => {
const { queryCacheKey, requestId } = promiseRef.current || {};
const stableArgValue = stableArg();
const stableSubscriptionOptionsValue = stableSubscriptionOptions();
const forceRefetchValue = forceRefetch();
const initialPageParamValue = initialPageParam();
// HACK We've saved the middleware subscription lookup callbacks into a ref,
// so we can directly check here if the subscription exists for this query.
let currentRenderHasSubscription = false;
if (queryCacheKey && requestId) {
currentRenderHasSubscription = !!subscriptionSelectorsRef?.isRequestSubscribed(queryCacheKey, requestId);
}
const subscriptionRemoved = !currentRenderHasSubscription && lastRenderHadSubscription;
lastRenderHadSubscription = currentRenderHasSubscription;
if (subscriptionRemoved) {
promiseRef.current = undefined;
}
const lastPromise = promiseRef;
if (stableArgValue === skipToken) {
lastPromise.current?.unsubscribe();
promiseRef.current = undefined;
return;
}
const lastSubscriptionOptions = promiseRef.current?.subscriptionOptions;
if (!lastPromise.current || lastPromise.current.arg !== stableArgValue) {
lastPromise.current?.unsubscribe();
const promise = dispatch(initiate(stableArgValue, {
subscriptionOptions: stableSubscriptionOptionsValue,
forceRefetch: forceRefetchValue,
...(isInfiniteQueryDefinition(context.endpointDefinitions[endpointName])
? {
initialPageParam: initialPageParamValue,
}
: {}),
}));
promiseRef.current = promise;
}
else if (stableSubscriptionOptionsValue !== lastSubscriptionOptions) {
lastPromise.current.updateSubscriptionOptions(stableSubscriptionOptionsValue);
}
}, { allowSignalWrites: true });
return [promiseRef, dispatch, initiate, stableSubscriptionOptions];
}
function buildUseQueryState(endpointName, preSelector) {
const useQueryState = (arg, options = {}) => {
const { select } = api.endpoints[endpointName];
// We need to use `toLazySignal` here to prevent 'signal required inputs' errors
const lazyArg = typeof arg === 'function' ? toLazySignal(arg, { initialValue: skipToken }) : () => arg;
const lazyOptions = typeof options === 'function'
? toLazySignal(options, { initialValue: { selectFromResult: noPendingQueryStateSelector } })
: () => options;
const stateOptions = computed(() => {
const { skip = false, selectFromResult } = lazyOptions();
return { skip, selectFromResult };
});
const subscriptionArg = computed(() => {
const subscriptionArg = lazyArg();
return stateOptions().skip ? skipToken : subscriptionArg;
});
const stableArg = useStableQueryArgs(subscriptionArg, serializeQueryArgs, context.endpointDefinitions[endpointName], endpointName);
let lastValue;
const currentState = computed(() => {
const selectDefaultResult = createSelector(select(stableArg()), (subState) => preSelector(subState, lastValue, stableArg()));
const { selectFromResult } = stateOptions();
const querySelector = selectFromResult
? createSelector(selectDefaultResult, selectFromResult)
: selectDefaultResult;
const currentState = useSelector((state) => querySelector(state), {
equal: shallowEqual,
});
lastValue = selectDefaultResult(getState());
return currentState();
});
const deepSignal = toDeepSignal(currentState);
return deepSignal;
};
return useQueryState;
}
function usePromiseRefUnsubscribeOnUnmount(promiseRef) {
inject(DestroyRef).onDestroy(() => {
promiseRef.current?.unsubscribe?.();
promiseRef.current = undefined;
});
}
function refetchOrErrorIfUnmounted(promiseRef) {
if (!promiseRef.current)
throw new Error('Cannot refetch a query that has not been started yet.');
return promiseRef.current.refetch();
}
function buildQueryHooks(endpointName) {
const useQuerySubscription = (arg, options = {}) => {
const [promiseRef] = useQuerySubscriptionCommonImpl(endpointName, arg, options);
usePromiseRefUnsubscribeOnUnmount(promiseRef);
return {
/**
* A method to manually refetch data for the query
*/
refetch: () => refetchOrErrorIfUnmounted(promiseRef),
};
};
const useLazyQuerySubscription = (options = {}) => {
const { initiate } = api.endpoints[endpointName];
const subscriptionArg = signal(UNINITIALIZED_VALUE);
let promiseRef;
const stableSubscriptionOptions = computed(() => {
const { refetchOnReconnect, refetchOnFocus, pollingInterval = 0, skipPollingIfUnfocused = false, } = typeof options === 'function' ? options() : options;
return { refetchOnReconnect, refetchOnFocus, pollingInterval, skipPollingIfUnfocused };
}, { equal: shallowEqual });
effect(() => {
const lastSubscriptionOptions = promiseRef?.subscriptionOptions;
if (stableSubscriptionOptions() !== lastSubscriptionOptions) {
promiseRef?.updateSubscriptionOptions(stableSubscriptionOptions());
}
}, { allowSignalWrites: true });
let subscriptionOptionsRef = stableSubscriptionOptions();
effect(() => {
subscriptionOptionsRef = stableSubscriptionOptions();
});
const trigger = (arg, { preferCacheValue = false } = {}) => {
let promise;
promiseRef?.unsubscribe();
promiseRef = promise = dispatch(initiate(arg, { subscriptionOptions: subscriptionOptionsRef, forceRefetch: !preferCacheValue }));
subscriptionArg.set(arg);
return promise;
};
const reset = () => {
if (promiseRef?.queryCacheKey) {
dispatch(api.internalActions.removeQueryResult({
queryCacheKey: promiseRef?.queryCacheKey,
}));
}
};
/* cleanup on unmount */
inject(DestroyRef).onDestroy(() => {
promiseRef?.unsubscribe();
});
/* if "cleanup on unmount" was triggered from a fast refresh, we want to reinstate the query */
effect(() => {
if (subscriptionArg() !== UNINITIALIZED_VALUE && !promiseRef) {
trigger(subscriptionArg(), { preferCacheValue: true });
}
});
const lastArg = computed(() => (subscriptionArg() !== UNINITIALIZED_VALUE ? subscriptionArg() : skipToken), {
equal: shallowEqual,
});
return [trigger, lastArg, { reset }];
};
const useQueryState = buildUseQueryState(endpointName, queryStatePreSelector);
return {
useQueryState,
useQuerySubscription,
useLazyQuerySubscription,
useLazyQuery(options) {
const [trigger, arg, { reset }] = useLazyQuerySubscription(options);
const subscriptionOptions = computed(() => ({
...options,
skip: arg() === UNINITIALIZED_VALUE,
}));
const queryStateResults = useQueryState(arg, subscriptionOptions);
const signalsMap = signalProxy(queryStateResults);
Object.assign(trigger, { lastArg: arg, reset });
Object.assign(trigger, signalsMap);
return trigger;
},
useQuery(arg, options) {
const querySubscriptionResults = useQuerySubscription(arg, options);
const subscriptionOptions = computed(() => {
const subscriptionArg = typeof arg === 'function' ? arg() : arg;
const subscriptionOptions = typeof options === 'function' ? options() : options;
return {
selectFromResult: subscriptionArg === skipToken || subscriptionOptions?.skip ? undefined : noPendingQueryStateSelector,
...subscriptionOptions,
};
});
const queryStateResults = useQueryState(arg, subscriptionOptions);
Object.assign(queryStateResults, querySubscriptionResults);
return queryStateResults;
},
};
}
function buildInfiniteQueryHooks(endpointName) {
const useInfiniteQuerySubscription = (arg, options = {}) => {
const [promiseRef, dispatch, initiate, stableSubscriptionOptions] = useQuerySubscriptionCommonImpl(endpointName, arg, options);
let subscriptionOptionsRef = stableSubscriptionOptions();
effect(() => {
subscriptionOptionsRef = stableSubscriptionOptions();
});
const trigger = (arg, direction) => {
let promise;
promiseRef.current?.unsubscribe();
promiseRef.current = promise = dispatch(initiate(arg, {
subscriptionOptions: subscriptionOptionsRef,
direction,
}));
return promise;
};
usePromiseRefUnsubscribeOnUnmount(promiseRef);
const fetchNextPage = () => {
return trigger(arg, 'forward');
};
const fetchPreviousPage = () => {
return trigger(arg, 'backward');
};
return {
trigger,
/**
* A method to manually refetch data for the query
*/
refetch: () => refetchOrErrorIfUnmounted(promiseRef),
fetchNextPage,
fetchPreviousPage,
};
};
const useInfiniteQueryState = buildUseQueryState(endpointName, infiniteQueryStatePreSelector);
return {
useInfiniteQueryState,
useInfiniteQuerySubscription,
useInfiniteQuery(arg, options) {
const { refetch, fetchNextPage, fetchPreviousPage } = useInfiniteQuerySubscription(arg, options);
const subscriptionOptions = computed(() => {
const subscriptionArg = typeof arg === 'function' ? arg() : arg;
const subscriptionOptions = typeof options === 'function' ? options() : options;
return {
selectFromResult: subscriptionArg === skipToken || subscriptionOptions?.skip ? undefined : noPendingQueryStateSelector,
...subscriptionOptions,
};
});
const queryStateResults = useInfiniteQueryState(arg, subscriptionOptions);
Object.assign(queryStateResults, { fetchNextPage, fetchPreviousPage, refetch });
return queryStateResults;
},
};
}
function buildMutationHook(name) {
const { initiate, select } = api.endpoints[name];
const useMutation = ({ selectFromResult, fixedCacheKey } = {}) => {
const promiseRef = signal(undefined);
effect((onCleanup) => {
const currentPromise = promiseRef();
onCleanup(() => {
if (!currentPromise?.arg.fixedCacheKey) {
untracked(() => currentPromise?.reset());
}
});
});
const triggerMutation = (arg) => {
const promise = dispatch(initiate(arg, { fixedCacheKey }));
promiseRef.set(promise);
return promise;
};
const fixedSelect = (args) => (state) => {
const currentState = select(args)(state);
return {
...currentState,
// Deep signals required init properties undefined atleast
data: currentState.data,
endpointName: currentState.endpointName,
error: currentState.error,
fulfilledTimeStamp: currentState.fulfilledTimeStamp,
requestId: currentState.requestId,
startedTimeStamp: currentState.startedTimeStamp,
};
};
const requestId = computed(() => promiseRef()?.requestId);
const selectDefaultResult = (requestId) => fixedSelect({ fixedCacheKey, requestId });
const mutationSelector = (requestId) => selectFromResult
? createSelector(selectDefaultResult(requestId), selectFromResult)
: selectDefaultResult(requestId);
const currentState = computed(() => useSelector(mutationSelector(requestId()), { equal: shallowEqual }));
const originalArgs = computed(() => (fixedCacheKey == null ? promiseRef()?.arg.originalArgs : undefined));
const reset = () => {
if (promiseRef()) {
promiseRef.set(undefined);
}
if (fixedCacheKey) {
dispatch(api.internalActions.removeMutationResult({
requestId: requestId(),
fixedCacheKey,
}));
}
};
const finalState = computed(() => currentState()());
const signalsMap = signalProxy(finalState);
Object.assign(triggerMutation, { originalArgs });
Object.assign(triggerMutation, { reset });
Object.assign(triggerMutation, signalsMap);
return triggerMutation;
};
return { useMutation };
}
}
const angularHooksModuleName = /* @__PURE__ */ Symbol();
/**
* Creates a module that generates angular hooks from endpoints, for use with `buildCreateApi`.
*
* @example
* ```ts
* const customCreateApi = buildCreateApi(
* coreModule(),
* angularHooksModule(() => myCreateAngularHooksModule())
* );
* ```
*
* @returns A module for use with `buildCreateApi`
*/
const angularHooksModule = ({ hooks, createSelector, getInjector, }) => {
return {
name: angularHooksModuleName,
init(api, { serializeQueryArgs }, context) {
const anyApi = api;
const { buildQueryHooks, buildInfiniteQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
api,
moduleOptions: { hooks, createSelector, getInjector },
serializeQueryArgs,
context,
});
safeAssign(anyApi, { usePrefetch });
safeAssign(anyApi, { dispatch: hooks.dispatch });
safeAssign(anyApi, { selectSignal: hooks.useSelector });
safeAssign(anyApi, { getInjector });
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;
}
if (isMutationDefinition(definition)) {
const { useMutation } = buildMutationHook(endpointName);
safeAssign(anyApi.endpoints[endpointName], { useMutation });
api[`use${capitalize(endpointName)}Mutation`] = useMutation;
}
else if (isInfiniteQueryDefinition(definition)) {
const { useInfiniteQuery, useInfiniteQuerySubscription, useInfiniteQueryState } = buildInfiniteQueryHooks(endpointName);
safeAssign(anyApi.endpoints[endpointName], {
useInfiniteQuery,
useInfiniteQuerySubscription,
useInfiniteQueryState,
});
api[`use${capitalize(endpointName)}InfiniteQuery`] = useInfiniteQuery;
}
},
};
},
};
};
function fetchBaseQuery(paramsOrFactory = {}) {
if (typeof paramsOrFactory === 'object')
return fetchBaseQuery$1(paramsOrFactory);
return async (args, api, extraOptions) => {
const injector = api.extra.injector;
const baseQuery = runInInjectionContext(injector, paramsOrFactory);
return await baseQuery(args, api, extraOptions);
};
}
const createApi = (options) => {
const next = (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, { injector: getInjector() });
}
return store.hooks.dispatch(action);
};
const dispatch = (action) => {
if (!store) {
const reducerPath = options.reducerPath;
throw new Error(`Provide the API (${reducerPath}) is necessary to use the queries. Did you forget to provide the queries api?`);
}
return middleware(next)(action);
};
const getState = () => store.hooks.getState();
const useSelector = (mapFn, options) => store?.hooks.useSelector(mapFn, options);
const createSelector = (...input) => store.createSelector(...input);
const getInjector = () => store.getInjector();
const createApi = /* @__PURE__ */ buildCreateApi(coreModule(), angularHooksModule({
hooks: {
dispatch: dispatch,
getState,
useSelector,
},
createSelector,
getInjector,
}));
const api = createApi(options);
let store;
const initApiStore = (setupFn) => {
store = setupFn();
};
Object.assign(api, { initApiStore });
const middleware = api.middleware({ dispatch, getState });
return api;
};
/**
* Generated bundle index. Do not edit.
*/
export { UNINITIALIZED_VALUE, angularHooksModule, createApi, fetchBaseQuery, shallowEqual };
//# sourceMappingURL=ngrx-rtk-query-core.mjs.map