@leancodepl/react-query-cqrs-client 7.8.2 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var reactQuery = require('@tanstack/react-query');
6
4
  var rxjs = require('rxjs');
7
5
  var ajax = require('rxjs/ajax');
@@ -92,6 +90,7 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
92
90
  queryFn: (context)=>rxjs.firstValueFrom(useApiQuery.fetcher(data, context))
93
91
  }, options), queryClient);
94
92
  }
93
+ useApiQuery.type = type;
95
94
  useApiQuery.fetcher = (data, context)=>rxjs.race([
96
95
  fetcher(data).pipe(uncapitalizedParse()),
97
96
  ...(context == null ? void 0 : context.signal) ? [
@@ -143,6 +142,15 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
143
142
  useApiQuery.invalidate = (query)=>queryClient.invalidateQueries({
144
143
  queryKey: useApiQuery.key(query)
145
144
  });
145
+ useApiQuery.cancel = (query)=>queryClient.cancelQueries({
146
+ queryKey: useApiQuery.key(query)
147
+ });
148
+ useApiQuery.optimisticUpdate = async (updater, query = {})=>{
149
+ await useApiQuery.cancel(query);
150
+ const data = useApiQuery.getQueriesData(query);
151
+ useApiQuery.setQueriesData(query, updater);
152
+ return ()=>data.forEach(([key, result])=>queryClient.setQueryData(key, result));
153
+ };
146
154
  return useApiQuery;
147
155
  },
148
156
  createOperation (type) {
@@ -162,25 +170,31 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
162
170
  }, options, {
163
171
  async onSuccess (data, variables, context) {
164
172
  const result = await (onSuccessBase == null ? void 0 : onSuccessBase(data, variables, context));
165
- invalidateQueries && await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
166
- queryKey
167
- })));
173
+ if (invalidateQueries) {
174
+ await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
175
+ queryKey
176
+ })));
177
+ }
168
178
  return result;
169
179
  }
170
180
  }), queryClient);
171
181
  }
182
+ useApiOperation.type = type;
172
183
  useApiOperation.fetcher = (variables)=>fetcher(variables).pipe(uncapitalizedParse());
173
184
  return useApiOperation;
174
185
  },
175
186
  createCommand (type, errorCodes) {
176
187
  const fetcher = mkFetcher(`command/${type}`);
177
188
  function useApiCommand(_param = {}) {
178
- var { invalidateQueries, handler, onSuccess } = _param, options = _object_without_properties_loose(_param, [
189
+ var { invalidateQueries, handler, optimisticUpdate, onSuccess, onMutate, onError } = _param, options = _object_without_properties_loose(_param, [
179
190
  "invalidateQueries",
180
191
  "handler",
181
- "onSuccess"
192
+ "optimisticUpdate",
193
+ "onSuccess",
194
+ "onMutate",
195
+ "onError"
182
196
  ]);
183
- return reactQuery.useMutation(_extends({
197
+ return reactQuery.useMutation(_extends({}, options, {
184
198
  mutationKey: [
185
199
  type
186
200
  ],
@@ -189,17 +203,32 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
189
203
  return rxjs.firstValueFrom(useApiCommand.fetcher(variables));
190
204
  }
191
205
  return rxjs.firstValueFrom(useApiCommand.call(variables, handler));
192
- }
193
- }, options, {
206
+ },
207
+ async onMutate (variables) {
208
+ // there's really no good way to do it without type cast
209
+ const baseContext = await (onMutate == null ? void 0 : onMutate(variables));
210
+ var _optimisticUpdate;
211
+ const optimisticUpdateReverts = await Promise.all((_optimisticUpdate = optimisticUpdate == null ? void 0 : optimisticUpdate(variables)) != null ? _optimisticUpdate : []);
212
+ return _extends({}, baseContext, {
213
+ revertOptimisticUpdate: ()=>optimisticUpdateReverts.forEach((revertOptimisticUpdate)=>revertOptimisticUpdate())
214
+ });
215
+ },
194
216
  async onSuccess (data, variables, context) {
195
- invalidateQueries && await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
196
- queryKey
197
- })));
217
+ if (invalidateQueries) {
218
+ await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
219
+ queryKey
220
+ })));
221
+ }
198
222
  const result = await (onSuccess == null ? void 0 : onSuccess(data, variables, context));
199
223
  return result;
224
+ },
225
+ async onError (error, variables, context) {
226
+ await (onError == null ? void 0 : onError(error, variables, context));
227
+ context == null ? void 0 : context.revertOptimisticUpdate();
200
228
  }
201
229
  }), queryClient);
202
230
  }
231
+ useApiCommand.type = type;
203
232
  useApiCommand.fetcher = (variables)=>fetcher(variables);
204
233
  useApiCommand.call = (variables, handler)=>{
205
234
  const $response = useApiCommand.fetcher(variables);
package/index.esm.js CHANGED
@@ -88,6 +88,7 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
88
88
  queryFn: (context)=>firstValueFrom(useApiQuery.fetcher(data, context))
89
89
  }, options), queryClient);
90
90
  }
91
+ useApiQuery.type = type;
91
92
  useApiQuery.fetcher = (data, context)=>race([
92
93
  fetcher(data).pipe(uncapitalizedParse()),
93
94
  ...(context == null ? void 0 : context.signal) ? [
@@ -139,6 +140,15 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
139
140
  useApiQuery.invalidate = (query)=>queryClient.invalidateQueries({
140
141
  queryKey: useApiQuery.key(query)
141
142
  });
143
+ useApiQuery.cancel = (query)=>queryClient.cancelQueries({
144
+ queryKey: useApiQuery.key(query)
145
+ });
146
+ useApiQuery.optimisticUpdate = async (updater, query = {})=>{
147
+ await useApiQuery.cancel(query);
148
+ const data = useApiQuery.getQueriesData(query);
149
+ useApiQuery.setQueriesData(query, updater);
150
+ return ()=>data.forEach(([key, result])=>queryClient.setQueryData(key, result));
151
+ };
142
152
  return useApiQuery;
143
153
  },
144
154
  createOperation (type) {
@@ -158,25 +168,31 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
158
168
  }, options, {
159
169
  async onSuccess (data, variables, context) {
160
170
  const result = await (onSuccessBase == null ? void 0 : onSuccessBase(data, variables, context));
161
- invalidateQueries && await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
162
- queryKey
163
- })));
171
+ if (invalidateQueries) {
172
+ await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
173
+ queryKey
174
+ })));
175
+ }
164
176
  return result;
165
177
  }
166
178
  }), queryClient);
167
179
  }
180
+ useApiOperation.type = type;
168
181
  useApiOperation.fetcher = (variables)=>fetcher(variables).pipe(uncapitalizedParse());
169
182
  return useApiOperation;
170
183
  },
171
184
  createCommand (type, errorCodes) {
172
185
  const fetcher = mkFetcher(`command/${type}`);
173
186
  function useApiCommand(_param = {}) {
174
- var { invalidateQueries, handler, onSuccess } = _param, options = _object_without_properties_loose(_param, [
187
+ var { invalidateQueries, handler, optimisticUpdate, onSuccess, onMutate, onError } = _param, options = _object_without_properties_loose(_param, [
175
188
  "invalidateQueries",
176
189
  "handler",
177
- "onSuccess"
190
+ "optimisticUpdate",
191
+ "onSuccess",
192
+ "onMutate",
193
+ "onError"
178
194
  ]);
179
- return useMutation(_extends({
195
+ return useMutation(_extends({}, options, {
180
196
  mutationKey: [
181
197
  type
182
198
  ],
@@ -185,17 +201,32 @@ function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider, ajaxOptions })
185
201
  return firstValueFrom(useApiCommand.fetcher(variables));
186
202
  }
187
203
  return firstValueFrom(useApiCommand.call(variables, handler));
188
- }
189
- }, options, {
204
+ },
205
+ async onMutate (variables) {
206
+ // there's really no good way to do it without type cast
207
+ const baseContext = await (onMutate == null ? void 0 : onMutate(variables));
208
+ var _optimisticUpdate;
209
+ const optimisticUpdateReverts = await Promise.all((_optimisticUpdate = optimisticUpdate == null ? void 0 : optimisticUpdate(variables)) != null ? _optimisticUpdate : []);
210
+ return _extends({}, baseContext, {
211
+ revertOptimisticUpdate: ()=>optimisticUpdateReverts.forEach((revertOptimisticUpdate)=>revertOptimisticUpdate())
212
+ });
213
+ },
190
214
  async onSuccess (data, variables, context) {
191
- invalidateQueries && await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
192
- queryKey
193
- })));
215
+ if (invalidateQueries) {
216
+ await Promise.allSettled(invalidateQueries.map((queryKey)=>queryClient.invalidateQueries({
217
+ queryKey
218
+ })));
219
+ }
194
220
  const result = await (onSuccess == null ? void 0 : onSuccess(data, variables, context));
195
221
  return result;
222
+ },
223
+ async onError (error, variables, context) {
224
+ await (onError == null ? void 0 : onError(error, variables, context));
225
+ context == null ? void 0 : context.revertOptimisticUpdate();
196
226
  }
197
227
  }), queryClient);
198
228
  }
229
+ useApiCommand.type = type;
199
230
  useApiCommand.fetcher = (variables)=>fetcher(variables);
200
231
  useApiCommand.call = (variables, handler)=>{
201
232
  const $response = useApiCommand.fetcher(variables);
package/package.json CHANGED
@@ -1,22 +1,28 @@
1
1
  {
2
2
  "name": "@leancodepl/react-query-cqrs-client",
3
- "version": "7.8.2",
3
+ "version": "8.1.0",
4
4
  "license": "Apache-2.0",
5
5
  "dependencies": {
6
- "@leancodepl/cqrs-client-base": "7.8.2",
7
- "@leancodepl/utils": "7.8.2",
8
- "@leancodepl/validation": "7.8.2",
6
+ "@leancodepl/cqrs-client-base": "8.1.0",
7
+ "@leancodepl/utils": "8.1.0",
8
+ "@leancodepl/validation": "8.1.0",
9
9
  "@tanstack/react-query": ">=5.0.0",
10
10
  "rxjs": ">=7.0.0"
11
11
  },
12
+ "devDependencies": {
13
+ "@testing-library/react": "*",
14
+ "react": "*"
15
+ },
12
16
  "exports": {
13
17
  "./package.json": "./package.json",
14
18
  ".": {
15
19
  "module": "./index.esm.js",
20
+ "types": "./index.esm.d.ts",
16
21
  "import": "./index.cjs.mjs",
17
22
  "default": "./index.cjs.js"
18
23
  }
19
24
  },
20
25
  "module": "./index.esm.js",
21
- "main": "./index.cjs.js"
26
+ "main": "./index.cjs.js",
27
+ "types": "./index.esm.d.ts"
22
28
  }
@@ -12,12 +12,13 @@ export declare function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider,
12
12
  ajaxOptions?: Omit<AjaxConfig, "body" | "headers" | "method" | "responseType" | "url">;
13
13
  }): {
14
14
  createQuery<TQuery, TResult>(type: string): {
15
- (data: TQuery, options?: Omit<UndefinedInitialDataOptions<NullableUncapitalizeDeep<TResult>, unknown>, "queryFn" | "queryKey"> | undefined): import("@tanstack/react-query").UseQueryResult<NullableUncapitalizeDeep<TResult>, unknown>;
15
+ (data: TQuery, options?: Omit<UndefinedInitialDataOptions<NullableUncapitalizeDeep<TResult>, unknown>, "queryFn" | "queryKey">): import("@tanstack/react-query").UseQueryResult<NullableUncapitalizeDeep<TResult>, unknown>;
16
+ type: string;
16
17
  fetcher(data: TQuery, context?: QueryFunctionContext<QueryKey>): Observable<NullableUncapitalizeDeep<TResult>>;
17
- fetch(data: TQuery, options?: Omit<FetchQueryOptions<NullableUncapitalizeDeep<TResult>, unknown, NullableUncapitalizeDeep<TResult>, QueryKey, never>, "queryFn" | "queryKey"> | undefined): Promise<NullableUncapitalizeDeep<TResult>>;
18
+ fetch(data: TQuery, options?: Omit<FetchQueryOptions<NullableUncapitalizeDeep<TResult>, unknown>, "queryFn" | "queryKey">): Promise<NullableUncapitalizeDeep<TResult>>;
18
19
  lazy<TContext = unknown>(options?: Omit<UseMutationOptions<NullableUncapitalizeDeep<TResult>, unknown, TQuery, TContext>, "mutationFn" | "mutationKey">): UseMutationResult<NullableUncapitalizeDeep<TResult>, unknown, TQuery, TContext>;
19
20
  infinite(data: TQuery, options: {
20
- pageParamKey?: keyof TQuery | undefined;
21
+ pageParamKey?: keyof TQuery;
21
22
  } & Omit<UndefinedInitialDataInfiniteOptions<NullableUncapitalizeDeep<TResult>, unknown>, "queryFn" | "queryKey">): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<NullableUncapitalizeDeep<TResult>, unknown>, unknown>;
22
23
  key(query: Partial<TQuery>): readonly [string, Partial<TQuery>];
23
24
  setQueryData: {
@@ -27,38 +28,44 @@ export declare function mkCqrsClient({ cqrsEndpoint, queryClient, tokenProvider,
27
28
  setQueriesData(query: Partial<TQuery>, updater: Updater<NullableUncapitalizeDeep<TResult> | undefined, NullableUncapitalizeDeep<TResult> | undefined>): [QueryKey, NullableUncapitalizeDeep<TResult> | undefined][];
28
29
  getQueryData(query: TQuery): NullableUncapitalizeDeep<TResult> | undefined;
29
30
  getQueriesData(query: Partial<TQuery>): [QueryKey, NullableUncapitalizeDeep<TResult> | undefined][];
30
- prefetch(data: TQuery, options?: Omit<FetchQueryOptions<NullableUncapitalizeDeep<TResult>, unknown, NullableUncapitalizeDeep<TResult>, QueryKey, never>, "queryFn" | "queryKey" | "initialData"> | undefined): Promise<void>;
31
+ prefetch(data: TQuery, options?: Omit<FetchQueryOptions<NullableUncapitalizeDeep<TResult>, unknown>, "initialData" | "queryFn" | "queryKey">): Promise<void>;
31
32
  invalidate(query: Partial<TQuery>): Promise<void>;
33
+ cancel(query: Partial<TQuery>): Promise<void>;
34
+ optimisticUpdate(updater: Updater<NullableUncapitalizeDeep<TResult> | undefined, NullableUncapitalizeDeep<TResult> | undefined>, query?: Partial<TQuery>): Promise<() => void>;
32
35
  };
33
- createOperation<TOperation, TResult_1>(type: string): {
34
- <TContext_1 = unknown>({ onSuccess: onSuccessBase, invalidateQueries, ...options }?: {
35
- invalidateQueries?: QueryKey[] | undefined;
36
- } & Omit<UseMutationOptions<NullableUncapitalizeDeep<TResult_1>, unknown, TOperation, TContext_1>, "mutationFn" | "mutationKey">): UseMutationResult<NullableUncapitalizeDeep<TResult_1>, unknown, TOperation, TContext_1>;
37
- fetcher(variables: TOperation): Observable<NullableUncapitalizeDeep<TResult_1>>;
36
+ createOperation<TOperation, TResult>(type: string): {
37
+ <TContext = unknown>({ onSuccess: onSuccessBase, invalidateQueries, ...options }?: {
38
+ invalidateQueries?: QueryKey[];
39
+ } & Omit<UseMutationOptions<NullableUncapitalizeDeep<TResult>, unknown, TOperation, TContext>, "mutationFn" | "mutationKey">): UseMutationResult<NullableUncapitalizeDeep<TResult>, unknown, TOperation, TContext>;
40
+ type: string;
41
+ fetcher(variables: TOperation): Observable<NullableUncapitalizeDeep<TResult>>;
38
42
  };
39
43
  createCommand<TCommand, TErrorCodes extends {
40
44
  [name: string]: number;
41
45
  }>(type: string, errorCodes: TErrorCodes): {
42
- <TContext_2 = unknown>(options?: ({
43
- invalidateQueries?: QueryKey[] | undefined;
46
+ <TContext extends Record<string, unknown> = {}>(options?: {
47
+ invalidateQueries?: QueryKey[];
44
48
  handler?: undefined;
45
- } & Omit<UseMutationOptions<CommandResult<TErrorCodes>, unknown, TCommand, TContext_2>, "mutationFn" | "mutationKey">) | undefined): UseMutationResult<CommandResult<TErrorCodes>, unknown, TCommand, TContext_2>;
46
- <TResult_2, TContext_3 = unknown>(options?: ({
47
- invalidateQueries?: QueryKey[] | undefined;
49
+ optimisticUpdate?: (variables: TCommand) => Promise<() => void>[];
50
+ } & Omit<UseMutationOptions<CommandResult<TErrorCodes>, unknown, TCommand, TContext>, "mutationFn" | "mutationKey">): UseMutationResult<CommandResult<TErrorCodes>, unknown, TCommand, TContext>;
51
+ <TResult, TContext extends Record<string, unknown> = {}>(options?: {
52
+ invalidateQueries?: QueryKey[];
48
53
  handler: (handler: ValidationErrorsHandler<{
49
54
  success: -1;
50
55
  failure: -2;
51
- } & TErrorCodes, never>) => TResult_2;
52
- } & Omit<UseMutationOptions<TResult_2, unknown, TCommand, TContext_3>, "mutationFn" | "mutationKey">) | undefined): UseMutationResult<TResult_2, unknown, TCommand, TContext_3>;
56
+ } & TErrorCodes, never>) => TResult;
57
+ optimisticUpdate?: (variables: TCommand) => Promise<() => void>[];
58
+ } & Omit<UseMutationOptions<TResult, unknown, TCommand, TContext>, "mutationFn" | "mutationKey">): UseMutationResult<TResult, unknown, TCommand, TContext>;
59
+ type: string;
53
60
  fetcher(variables: TCommand): Observable<CommandResult<TErrorCodes>>;
54
- call<TResult_3>(variables: TCommand, handler: (handler: ValidationErrorsHandler<{
61
+ call<TResult>(variables: TCommand, handler: (handler: ValidationErrorsHandler<{
55
62
  success: -1;
56
63
  failure: -2;
57
- } & TErrorCodes, never>) => TResult_3): Observable<TResult_3>;
64
+ } & TErrorCodes, never>) => TResult): Observable<TResult>;
58
65
  mapError(e: unknown): ApiResponse<CommandResult<TErrorCodes>>;
59
- handleResponse<TResult_4>(handler: (handler: ValidationErrorsHandler<{
66
+ handleResponse<TResult>(handler: (handler: ValidationErrorsHandler<{
60
67
  success: -1;
61
68
  failure: -2;
62
- } & TErrorCodes, never>) => TResult_4): (response: ApiResponse<CommandResult<TErrorCodes>>) => TResult_4;
69
+ } & TErrorCodes, never>) => TResult): (response: ApiResponse<CommandResult<TErrorCodes>>) => TResult;
63
70
  };
64
71
  };