Skip to content

Commit 49f5c7a

Browse files
phryneasmsutkowski
andauthored
split up into "core" & "redux-hooks" module (#116)
Co-authored-by: Matt Sutkowski <[email protected]>
1 parent 346ef24 commit 49f5c7a

28 files changed

+547
-386
lines changed

examples/svelte/src/main.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import App from './App.svelte';
22
import { worker } from './mocks/browser';
33

4-
worker.start();
5-
6-
const app = new App({
7-
target: document.body,
8-
});
4+
// Defer the load to ensure the worker has started.
5+
const app = worker.start({ onUnhandledRequest: 'error' }).then(
6+
() =>
7+
new App({
8+
target: document.body,
9+
}),
10+
);
911

1012
export default app;

examples/svelte/src/services/counter.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import { createApi, fetchBaseQuery } from '@rtk-incubator/rtk-query';
1+
import { createApi, fetchBaseQuery, retry } from '@rtk-incubator/rtk-query';
22

33
interface CountResponse {
44
count: number;
55
}
66

7-
export const counterApi = createApi({
8-
reducerPath: 'counterApi',
9-
baseQuery: fetchBaseQuery({
7+
const baseQuery = retry(
8+
fetchBaseQuery({
109
baseUrl: '/',
1110
}),
11+
);
12+
export const counterApi = createApi({
13+
reducerPath: 'counterApi',
14+
baseQuery,
1215
entityTypes: ['Counter'],
1316
endpoints: (build) => ({
1417
getCount: build.query<CountResponse, void>({

src/apiTypes.ts

Lines changed: 44 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,54 @@
1-
/**
2-
* Note: this file should import all other files for type discovery and declaration merging
3-
*/
4-
import { PatchQueryResultThunk, QueryApi, UpdateQueryResultThunk } from './buildThunks';
5-
import { AnyAction, Middleware, Reducer, ThunkDispatch, ThunkAction } from '@reduxjs/toolkit';
6-
import { PrefetchOptions } from './buildHooks';
7-
import {
8-
EndpointDefinitions,
9-
EndpointBuilder,
10-
QueryArgFrom,
11-
QueryDefinition,
12-
MutationDefinition,
13-
} from './endpointDefinitions';
14-
import { CombinedState, QueryKeys, RootState } from './apiState';
15-
import { UnionToIntersection } from './tsHelpers';
16-
import { TS41Hooks } from './ts41Types';
17-
import './buildSelectors';
18-
import { SliceActions } from './buildSlice';
19-
import { onFocus, onFocusLost, onOffline, onOnline } from './setupListeners';
1+
import { EndpointDefinitions, EndpointBuilder, EndpointDefinition } from './endpointDefinitions';
2+
import { UnionToIntersection, Id } from './tsHelpers';
3+
import { CoreModule } from './core/module';
4+
import { CreateApiOptions } from './createApi';
5+
import { BaseQueryFn } from './baseQueryTypes';
206

21-
type UnwrapPromise<T> = T extends PromiseLike<infer V> ? V : T;
22-
type MaybePromise<T> = T | PromiseLike<T>;
23-
24-
export type BaseQueryFn<Args = any, Result = unknown, Error = unknown, DefinitionExtraOptions = {}> = (
25-
args: Args,
26-
api: QueryApi,
27-
extraOptions: DefinitionExtraOptions
28-
) => MaybePromise<{ error: Error; data?: undefined } | { error?: undefined; data?: Result }>;
29-
30-
export type BaseQueryEnhancer<AdditionalArgs = unknown, AdditionalDefinitionExtraOptions = unknown, Config = void> = <
31-
BaseQuery extends BaseQueryFn
32-
>(
33-
baseQuery: BaseQuery,
34-
config: Config
35-
) => BaseQueryFn<
36-
BaseQueryArg<BaseQuery> & AdditionalArgs,
37-
BaseQueryResult<BaseQuery>,
38-
BaseQueryError<BaseQuery>,
39-
BaseQueryExtraOptions<BaseQuery> & AdditionalDefinitionExtraOptions
40-
>;
41-
42-
export type BaseQueryResult<BaseQuery extends BaseQueryFn> = Exclude<
43-
UnwrapPromise<ReturnType<BaseQuery>>,
44-
{ data: undefined }
45-
>['data'];
46-
47-
export type BaseQueryError<BaseQuery extends BaseQueryFn> = Exclude<
48-
UnwrapPromise<ReturnType<BaseQuery>>,
49-
{ error: undefined }
50-
>['error'];
51-
52-
export type BaseQueryArg<T extends (arg: any, ...args: any[]) => any> = T extends (arg: infer A, ...args: any[]) => any
53-
? A
54-
: any;
55-
56-
export type BaseQueryExtraOptions<BaseQuery extends BaseQueryFn> = Parameters<BaseQuery>[2];
57-
58-
export type Api<
7+
export interface ApiModules<
8+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
599
BaseQuery extends BaseQueryFn,
10+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
6011
Definitions extends EndpointDefinitions,
61-
ReducerPath extends string,
62-
EntityTypes extends string
63-
> = {
64-
reducerPath: ReducerPath;
65-
internalActions: InternalActions;
66-
reducer: Reducer<CombinedState<Definitions, EntityTypes, ReducerPath>, AnyAction>;
67-
middleware: Middleware<{}, RootState<Definitions, string, ReducerPath>, ThunkDispatch<any, any, AnyAction>>;
68-
util: {
69-
updateQueryResult: UpdateQueryResultThunk<Definitions, RootState<Definitions, string, ReducerPath>>;
70-
patchQueryResult: PatchQueryResultThunk<Definitions, RootState<Definitions, string, ReducerPath>>;
71-
};
72-
// If you actually care about the return value, use useQuery
73-
usePrefetch<EndpointName extends QueryKeys<Definitions>>(
74-
endpointName: EndpointName,
75-
options?: PrefetchOptions
76-
): (arg: QueryArgFrom<Definitions[EndpointName]>, options?: PrefetchOptions) => void;
77-
injectEndpoints<NewDefinitions extends EndpointDefinitions>(_: {
78-
endpoints: (build: EndpointBuilder<BaseQuery, EntityTypes, ReducerPath>) => NewDefinitions;
79-
overrideExisting?: boolean;
80-
}): Api<BaseQuery, Definitions & NewDefinitions, ReducerPath, EntityTypes>;
81-
endpoints: {
82-
[K in keyof Definitions]: Definitions[K] extends QueryDefinition<any, any, any, any, any>
83-
? ApiEndpointQuery<Definitions[K], Definitions>
84-
: Definitions[K] extends MutationDefinition<any, any, any, any, any>
85-
? ApiEndpointMutation<Definitions[K], Definitions>
86-
: never;
87-
};
88-
} & TS41Hooks<Definitions>;
89-
90-
export interface ApiEndpointQuery<
9112
// eslint-disable-next-line @typescript-eslint/no-unused-vars
92-
Definition extends QueryDefinition<any, any, any, any, any>,
13+
ReducerPath extends string,
9314
// eslint-disable-next-line @typescript-eslint/no-unused-vars
94-
Definitions extends EndpointDefinitions
15+
EntityTypes extends string
9516
> {}
9617

97-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
98-
export interface ApiEndpointMutation<
99-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
100-
Definition extends MutationDefinition<any, any, any, any, any>,
101-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
102-
Definitions extends EndpointDefinitions
103-
> {}
18+
export type ModuleName = keyof ApiModules<any, any, any, any>;
19+
20+
export type Module<Name extends ModuleName> = {
21+
name: Name;
22+
init<
23+
BaseQuery extends BaseQueryFn,
24+
Definitions extends EndpointDefinitions,
25+
ReducerPath extends string,
26+
EntityTypes extends string
27+
>(
28+
api: Api<BaseQuery, EndpointDefinitions, ReducerPath, EntityTypes, ModuleName>,
29+
options: Required<CreateApiOptions<BaseQuery, Definitions, ReducerPath, EntityTypes>>,
30+
context: {
31+
endpointDefinitions: Definitions;
32+
}
33+
): {
34+
injectEndpoint(endpoint: string, definition: EndpointDefinition<any, any, any, any>): void;
35+
};
36+
};
37+
38+
export type Api<
39+
BaseQuery extends BaseQueryFn,
40+
Definitions extends EndpointDefinitions,
41+
ReducerPath extends string,
42+
EntityTypes extends string,
43+
Enhancers extends ModuleName = CoreModule
44+
> = Id<
45+
Id<UnionToIntersection<ApiModules<BaseQuery, Definitions, ReducerPath, EntityTypes>[Enhancers]>> & {
46+
injectEndpoints<NewDefinitions extends EndpointDefinitions>(_: {
47+
endpoints: (build: EndpointBuilder<BaseQuery, EntityTypes, ReducerPath>) => NewDefinitions;
48+
overrideExisting?: boolean;
49+
}): Api<BaseQuery, Definitions & NewDefinitions, ReducerPath, EntityTypes, Enhancers>;
50+
}
51+
>;
10452

10553
export type ApiWithInjectedEndpoints<
10654
ApiDefinition extends Api<any, any, any, any>,
@@ -111,20 +59,3 @@ export type ApiWithInjectedEndpoints<
11159
Omit<Injections, 'endpoints'> & {
11260
endpoints: ApiDefinition['endpoints'] & Partial<UnionToIntersection<Injections[number]['endpoints']>>;
11361
};
114-
115-
export type InternalActions = SliceActions & {
116-
prefetchThunk: (endpointName: any, arg: any, options: PrefetchOptions) => ThunkAction<void, any, any, AnyAction>;
117-
} & {
118-
/**
119-
* Will cause the RTK Query middleware to trigger any refetchOnReconnect-related behavior
120-
* @link https://rtk-query-docs.netlify.app/api/setupListeners
121-
*/
122-
onOnline: typeof onOnline;
123-
onOffline: typeof onOffline;
124-
/**
125-
* Will cause the RTK Query middleware to trigger any refetchOnFocus-related behavior
126-
* @link https://rtk-query-docs.netlify.app/api/setupListeners
127-
*/
128-
onFocus: typeof onFocus;
129-
onFocusLost: typeof onFocusLost;
130-
};

src/baseQueryTypes.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { QueryApi } from './core/buildThunks';
2+
import { MaybePromise, UnwrapPromise } from './tsHelpers';
3+
4+
export type BaseQueryFn<Args = any, Result = unknown, Error = unknown, DefinitionExtraOptions = {}> = (
5+
args: Args,
6+
api: QueryApi,
7+
extraOptions: DefinitionExtraOptions
8+
) => MaybePromise<{ error: Error; data?: undefined } | { error?: undefined; data?: Result }>;
9+
10+
export type BaseQueryEnhancer<AdditionalArgs = unknown, AdditionalDefinitionExtraOptions = unknown, Config = void> = <
11+
BaseQuery extends BaseQueryFn
12+
>(
13+
baseQuery: BaseQuery,
14+
config: Config
15+
) => BaseQueryFn<
16+
BaseQueryArg<BaseQuery> & AdditionalArgs,
17+
BaseQueryResult<BaseQuery>,
18+
BaseQueryError<BaseQuery>,
19+
BaseQueryExtraOptions<BaseQuery> & AdditionalDefinitionExtraOptions
20+
>;
21+
22+
export type BaseQueryResult<BaseQuery extends BaseQueryFn> = Exclude<
23+
UnwrapPromise<ReturnType<BaseQuery>>,
24+
{ data: undefined }
25+
>['data'];
26+
27+
export type BaseQueryError<BaseQuery extends BaseQueryFn> = Exclude<
28+
UnwrapPromise<ReturnType<BaseQuery>>,
29+
{ error: undefined }
30+
>['error'];
31+
32+
export type BaseQueryArg<T extends (arg: any, ...args: any[]) => any> = T extends (arg: infer A, ...args: any[]) => any
33+
? A
34+
: any;
35+
36+
export type BaseQueryExtraOptions<BaseQuery extends BaseQueryFn> = Parameters<BaseQuery>[2];

src/apiState.ts renamed to src/core/apiState.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { SerializedError } from '@reduxjs/toolkit';
2-
import { BaseQueryError } from './apiTypes';
2+
import { BaseQueryError } from '../baseQueryTypes';
33
import {
44
QueryDefinition,
55
MutationDefinition,
66
EndpointDefinitions,
77
BaseEndpointDefinition,
88
ResultTypeFrom,
99
QueryArgFrom,
10-
} from './endpointDefinitions';
11-
import { Id, WithRequiredProp } from './tsHelpers';
10+
} from '../endpointDefinitions';
11+
import { Id, WithRequiredProp } from '../tsHelpers';
1212

1313
export type QueryCacheKey = string & { _type: 'queryCacheKey' };
1414
export type QuerySubstateIdentifier = { queryCacheKey: QueryCacheKey };

src/buildActionMaps.ts renamed to src/core/buildInitiate.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { EndpointDefinitions, QueryDefinition, MutationDefinition, QueryArgFrom } from './endpointDefinitions';
1+
import { EndpointDefinitions, QueryDefinition, MutationDefinition, QueryArgFrom } from '../endpointDefinitions';
22
import type { QueryThunkArg, MutationThunkArg } from './buildThunks';
33
import { AnyAction, AsyncThunk, ThunkAction } from '@reduxjs/toolkit';
44
import { MutationSubState, QueryStatus, QuerySubState, SubscriptionOptions } from './apiState';
5-
import { InternalSerializeQueryArgs } from './defaultSerializeQueryArgs';
6-
import { Api, ApiEndpointMutation, ApiEndpointQuery } from './apiTypes';
5+
import { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs';
6+
import { Api } from '../apiTypes';
7+
import { ApiEndpointMutation, ApiEndpointQuery } from './module';
78

8-
declare module './apiTypes' {
9+
declare module './module' {
910
export interface ApiEndpointQuery<
1011
Definition extends QueryDefinition<any, any, any, any, any>,
1112
Definitions extends EndpointDefinitions
@@ -63,7 +64,7 @@ export type MutationActionCreatorResult<D extends MutationDefinition<any, any, a
6364
unsubscribe(): void;
6465
};
6566

66-
export function buildActionMaps<Definitions extends EndpointDefinitions, InternalQueryArgs>({
67+
export function buildInitiate<InternalQueryArgs>({
6768
serializeQueryArgs,
6869
queryThunk,
6970
mutationThunk,
@@ -72,12 +73,12 @@ export function buildActionMaps<Definitions extends EndpointDefinitions, Interna
7273
serializeQueryArgs: InternalSerializeQueryArgs<InternalQueryArgs>;
7374
queryThunk: AsyncThunk<any, QueryThunkArg<any>, {}>;
7475
mutationThunk: AsyncThunk<any, MutationThunkArg<any>, {}>;
75-
api: Api<any, Definitions, any, string>;
76+
api: Api<any, EndpointDefinitions, any, string>;
7677
}) {
7778
const { unsubscribeQueryResult, unsubscribeMutationResult, updateSubscriptionOptions } = api.internalActions;
78-
return { buildQueryAction, buildMutationAction };
79+
return { buildInitiateQuery, buildInitiateMutation };
7980

80-
function buildQueryAction(endpoint: string, definition: QueryDefinition<any, any, any, any>) {
81+
function buildInitiateQuery(endpoint: string, definition: QueryDefinition<any, any, any, any>) {
8182
const queryAction: StartQueryActionCreator<any> = (
8283
arg,
8384
{ subscribe = true, forceRefetch, subscriptionOptions } = {}
@@ -123,7 +124,7 @@ export function buildActionMaps<Definitions extends EndpointDefinitions, Interna
123124
return queryAction;
124125
}
125126

126-
function buildMutationAction(
127+
function buildInitiateMutation(
127128
endpoint: string,
128129
definition: MutationDefinition<any, any, any, any>
129130
): StartMutationActionCreator<any> {

src/buildMiddleware.ts renamed to src/core/buildMiddleware.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { AnyAction, AsyncThunk, Middleware, MiddlewareAPI, ThunkDispatch } from '@reduxjs/toolkit';
22
import { batch as reactBatch } from 'react-redux';
33
import { QueryCacheKey, QueryStatus, QuerySubState, QuerySubstateIdentifier, RootState, Subscribers } from './apiState';
4-
import { Api } from './apiTypes';
4+
import { Api } from '../apiTypes';
55
import { MutationThunkArg, QueryThunkArg, ThunkResult } from './buildThunks';
66
import {
77
AssertEntityTypes,
88
calculateProvidedBy,
99
EndpointDefinitions,
1010
FullEntityDescription,
11-
} from './endpointDefinitions';
11+
} from '../endpointDefinitions';
1212
import { onFocus, onOnline } from './setupListeners';
13-
import { flatten } from './utils';
13+
import { flatten } from '../utils';
1414

1515
const batch = typeof reactBatch !== 'undefined' ? reactBatch : (fn: Function) => fn();
1616

@@ -29,7 +29,7 @@ export function buildMiddleware<Definitions extends EndpointDefinitions, Reducer
2929
endpointDefinitions: EndpointDefinitions;
3030
queryThunk: AsyncThunk<ThunkResult, QueryThunkArg<any>, {}>;
3131
mutationThunk: AsyncThunk<ThunkResult, MutationThunkArg<any>, {}>;
32-
api: Api<any, Definitions, ReducerPath, string>;
32+
api: Api<any, EndpointDefinitions, ReducerPath, string>;
3333
assertEntityType: AssertEntityTypes;
3434
}) {
3535
type MWApi = MiddlewareAPI<ThunkDispatch<any, any, AnyAction>, RootState<Definitions, string, ReducerPath>>;

src/buildSelectors.ts renamed to src/core/buildSelectors.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import {
1414
QueryArgFrom,
1515
EntityTypesFrom,
1616
ReducerPathFrom,
17-
} from './endpointDefinitions';
18-
import { InternalSerializeQueryArgs } from './defaultSerializeQueryArgs';
17+
} from '../endpointDefinitions';
18+
import { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs';
1919

2020
export const skipSelector = Symbol('skip selector');
2121

22-
declare module './apiTypes' {
22+
declare module './module' {
2323
export interface ApiEndpointQuery<
2424
Definition extends QueryDefinition<any, any, any, any, any>,
2525
Definitions extends EndpointDefinitions

src/buildSlice.ts renamed to src/core/buildSlice.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ import {
1515
ConfigState,
1616
} from './apiState';
1717
import type { MutationThunkArg, QueryThunkArg, ThunkResult } from './buildThunks';
18-
import { AssertEntityTypes, calculateProvidedBy, EndpointDefinitions } from './endpointDefinitions';
18+
import { AssertEntityTypes, calculateProvidedBy, EndpointDefinitions } from '../endpointDefinitions';
1919
import { applyPatches, Patch } from 'immer';
2020
import { onFocus, onFocusLost, onOffline, onOnline } from './setupListeners';
21-
import { isDocumentVisible, isOnline, copyWithStructuralSharing } from './utils';
21+
import { isDocumentVisible, isOnline, copyWithStructuralSharing } from '../utils';
2222

2323
function updateQuerySubstateIfExists(
2424
state: QueryState<any>,

0 commit comments

Comments
 (0)