Skip to content

Commit 18c317b

Browse files
committed
feat(lib): add noop store provider
1 parent 67f72ab commit 18c317b

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

examples/basic-ngrx-store/src/app/posts/api.ts

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const baseQuery = fetchBaseQuery({
1818
const baseQueryWithRetry = retry(baseQuery, { maxRetries: 6 });
1919

2020
export const postsApi = createApi({
21-
reducerPath: 'postsApi',
2221
baseQuery: baseQueryWithRetry,
2322
tagTypes: ['Posts'],
2423
endpoints: (build) => ({
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const TODO_NOOP_STORE = 'TODO';
1+
export * from './src/provide-noop-store-api';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {
2+
ENVIRONMENT_INITIALIZER,
3+
type EnvironmentProviders,
4+
Injector,
5+
type Signal,
6+
computed,
7+
inject,
8+
makeEnvironmentProviders,
9+
signal,
10+
} from '@angular/core';
11+
import { type Action } from '@ngrx/store';
12+
import { type SelectSignalOptions } from '@ngrx/store/src/models';
13+
import { type Reducer, type UnknownAction } from '@reduxjs/toolkit';
14+
import { type Api, setupListeners as setupListenersFn } from '@reduxjs/toolkit/query';
15+
16+
import { type AngularHooksModuleOptions, type Dispatch, shallowEqual } from 'ngrx-rtk-query/core';
17+
18+
const createNoopStoreApi = (
19+
api: Api<any, Record<string, any>, string, string, any>,
20+
{ injector = inject(Injector) }: { injector?: Injector } = {},
21+
) => {
22+
const reducerPath = api.reducerPath;
23+
const reducer = api.reducer as Reducer<any>;
24+
const state = signal<Record<string, any>>({});
25+
26+
return (): AngularHooksModuleOptions => {
27+
const getState = computed(() => ({ [reducerPath]: state() }));
28+
const dispatch = (action: Action) => {
29+
state.set(reducer(state(), action as UnknownAction));
30+
return action;
31+
};
32+
const useSelector = <K>(mapFn: (state: any) => K, options?: SelectSignalOptions<K>): Signal<K> =>
33+
computed(() => mapFn(getState()), { equal: options?.equal });
34+
35+
const hooks = { dispatch: dispatch as Dispatch, getState, useSelector };
36+
const createSelector = (...input: any[]) => {
37+
return computed(() => input.reduce((acc, selector) => selector(acc), getState()), { equal: shallowEqual });
38+
};
39+
const getInjector = () => injector;
40+
41+
return { hooks, createSelector, getInjector };
42+
};
43+
};
44+
45+
export interface StoreQueryConfig {
46+
setupListeners?: Parameters<typeof setupListenersFn>[1] | false;
47+
}
48+
49+
export function provideNoopStoreApi(
50+
api: Api<any, Record<string, any>, string, string, any>,
51+
{ setupListeners }: StoreQueryConfig = {},
52+
): EnvironmentProviders {
53+
setupListeners === false ? undefined : setupListenersFn(api.dispatch, setupListeners);
54+
55+
return makeEnvironmentProviders([
56+
{
57+
provide: ENVIRONMENT_INITIALIZER,
58+
multi: true,
59+
useValue() {
60+
api.initApiStore(createNoopStoreApi(api));
61+
},
62+
},
63+
]);
64+
}

0 commit comments

Comments
 (0)