@refinedev/core 4.38.4 → 4.40.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.
@@ -5,6 +5,8 @@ export declare type AutoSaveProps<TVariables> = {
5
5
  enabled: boolean;
6
6
  debounce?: number;
7
7
  onFinish?: (values: TVariables) => TVariables;
8
+ invalidateOnUnmount?: boolean;
9
+ invalidateOnClose?: boolean;
8
10
  };
9
11
  };
10
12
  export declare type AutoSaveReturnType<TData extends BaseRecord = BaseRecord, TError extends HttpError = HttpError, TVariables = {}> = {
@@ -1 +1 @@
1
- {"version":3,"file":"autoSave.d.ts","sourceRoot":"","sources":["../../src/interfaces/autoSave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,oBAAY,aAAa,CAAC,UAAU,IAAI;IACpC,QAAQ,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,CAAC;KACjD,CAAC;CACL,CAAC;AAEF,oBAAY,kBAAkB,CAC1B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA,aAAa,EAAE,IAAI,CACf,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAC9C,MAAM,GAAG,OAAO,GAAG,QAAQ,CAC9B,CAAC;IACF,gBAAgB,EAAE,CACd,MAAM,EAAE,UAAU,KACjB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,oBAAY,sBAAsB,CAC9B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA;;OAEG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9D;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC;IAChE;;OAEG;IACH,MAAM,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;CACpE,CAAC"}
1
+ {"version":3,"file":"autoSave.d.ts","sourceRoot":"","sources":["../../src/interfaces/autoSave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,oBAAY,aAAa,CAAC,UAAU,IAAI;IACpC,QAAQ,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,CAAC;QAC9C,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;CACL,CAAC;AAEF,oBAAY,kBAAkB,CAC1B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA,aAAa,EAAE,IAAI,CACf,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAC9C,MAAM,GAAG,OAAO,GAAG,QAAQ,CAC9B,CAAC;IACF,gBAAgB,EAAE,CACd,MAAM,EAAE,UAAU,KACjB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,oBAAY,sBAAsB,CAC9B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA;;OAEG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9D;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC;IAChE;;OAEG;IACH,MAAM,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;CACpE,CAAC"}
@@ -48,4 +48,5 @@ export * from "./bindings";
48
48
  export * from "./prettify";
49
49
  export * from "./autoSave";
50
50
  export * from "./textTransformers";
51
+ export * from "./optimistic-update-map";
51
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AAEtD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,aAAa,CAAC;AAG5B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,YAAY,CAAC;AAE3B,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACtC,oBAAY,UAAU,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC;AACF,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAElC,cAAc,QAAQ,CAAC;AAEvB,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AAEtD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,aAAa,CAAC;AAG5B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,YAAY,CAAC;AAE3B,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACtC,oBAAY,UAAU,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC;AACF,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAElC,cAAc,QAAQ,CAAC;AAEvB,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,oBAAoB,CAAC;AAEnC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { BaseKey, GetListResponse, GetManyResponse, GetOneResponse } from ".";
2
+ export declare type OptimisticUpdateMapType<TData, TVariables> = {
3
+ list?: ((previous: GetListResponse<TData> | null | undefined, values: TVariables, id: BaseKey) => GetListResponse<TData> | null) | boolean;
4
+ many?: ((previous: GetManyResponse<TData> | null | undefined, values: TVariables, id: BaseKey) => GetManyResponse<TData> | null) | boolean;
5
+ detail?: ((previous: GetOneResponse<TData> | null | undefined, values: TVariables, id: BaseKey) => GetOneResponse<TData> | null) | boolean;
6
+ };
7
+ export declare type OptimisticUpdateManyMapType<TData, TVariables> = {
8
+ list?: ((previous: GetListResponse<TData> | null | undefined, values: TVariables, ids: BaseKey[]) => GetListResponse<TData> | null) | boolean;
9
+ many?: ((previous: GetManyResponse<TData> | null | undefined, values: TVariables, ids: BaseKey[]) => GetManyResponse<TData> | null) | boolean;
10
+ detail?: ((previous: GetOneResponse<TData> | null | undefined, values: TVariables, id: BaseKey) => GetOneResponse<TData> | null) | boolean;
11
+ };
12
+ //# sourceMappingURL=optimistic-update-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimistic-update-map.d.ts","sourceRoot":"","sources":["../../src/interfaces/optimistic-update-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAE9E,oBAAY,uBAAuB,CAAC,KAAK,EAAE,UAAU,IAAI;IACrD,IAAI,CAAC,EACC,CAAC,CACG,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,OAAO,KACV,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GACnC,OAAO,CAAC;IACd,IAAI,CAAC,EACC,CAAC,CACG,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,OAAO,KACV,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GACnC,OAAO,CAAC;IACd,MAAM,CAAC,EACD,CAAC,CACG,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,OAAO,KACV,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAClC,OAAO,CAAC;CACjB,CAAC;AAEF,oBAAY,2BAA2B,CAAC,KAAK,EAAE,UAAU,IAAI;IACzD,IAAI,CAAC,EACC,CAAC,CACG,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,OAAO,EAAE,KACb,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GACnC,OAAO,CAAC;IACd,IAAI,CAAC,EACC,CAAC,CACG,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,OAAO,EAAE,KACb,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GACnC,OAAO,CAAC;IACd,MAAM,CAAC,EACD,CAAC,CACG,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,OAAO,KACV,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAClC,OAAO,CAAC;CACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refinedev/core",
3
- "version": "4.38.4",
3
+ "version": "4.40.0",
4
4
  "description": "refine is a React-based framework for building internal tools, rapidly. It ships with Ant Design System, an enterprise-level UI toolkit.",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -18,6 +18,9 @@ import {
18
18
  PreviousQuery,
19
19
  GetListResponse,
20
20
  IQueryKeys,
21
+ OptimisticUpdateMapType,
22
+ GetManyResponse,
23
+ GetOneResponse,
21
24
  } from "../../interfaces";
22
25
  import {
23
26
  useResource,
@@ -89,6 +92,15 @@ export type UpdateParams<TData, TError, TVariables> = {
89
92
  * You can use it to manage the invalidations that will occur at the end of the mutation.
90
93
  */
91
94
  invalidates?: Array<keyof IQueryKeys>;
95
+ /**
96
+ * You can use it to customize the optimistic update logic.
97
+ * @default {
98
+ * list: true,
99
+ * many: true,
100
+ * detail: true,
101
+ * }
102
+ */
103
+ optimisticUpdateMap?: OptimisticUpdateMapType<TData, TVariables>;
92
104
  } & SuccessErrorNotification<
93
105
  UpdateResponse<TData>,
94
106
  TError,
@@ -265,6 +277,7 @@ export const useUpdate = <
265
277
  dataProviderName,
266
278
  meta,
267
279
  metaData,
280
+ optimisticUpdateMap = { list: true, many: true, detail: true },
268
281
  }) => {
269
282
  const { identifier } = select(resourceName);
270
283
 
@@ -303,78 +316,128 @@ export const useUpdate = <
303
316
  );
304
317
 
305
318
  if (mutationModePropOrContext !== "pessimistic") {
306
- // Set the previous queries to the new ones:
307
- queryClient.setQueriesData(
308
- resourceKeys
309
- .action("list")
310
- .params(preferredMeta ?? {})
311
- .get(preferLegacyKeys),
312
- (previous?: GetListResponse<TData> | null) => {
313
- if (!previous) {
314
- return null;
315
- }
316
- const data = previous.data.map((record: TData) => {
317
- if (record.id?.toString() === id?.toString()) {
318
- return {
319
+ if (optimisticUpdateMap.list) {
320
+ // Set the previous queries to the new ones:
321
+ queryClient.setQueriesData(
322
+ resourceKeys
323
+ .action("list")
324
+ .params(preferredMeta ?? {})
325
+ .get(preferLegacyKeys),
326
+ (previous?: GetListResponse<TData> | null) => {
327
+ if (
328
+ typeof optimisticUpdateMap.list ===
329
+ "function"
330
+ ) {
331
+ return optimisticUpdateMap.list(
332
+ previous,
333
+ values,
319
334
  id,
320
- ...record,
321
- ...values,
322
- } as unknown as TData;
335
+ );
323
336
  }
324
- return record;
325
- });
326
337
 
327
- return {
328
- ...previous,
329
- data,
330
- };
331
- },
332
- );
338
+ if (!previous) {
339
+ return null;
340
+ }
333
341
 
334
- queryClient.setQueriesData(
335
- resourceKeys.action("many").get(preferLegacyKeys),
336
- (previous?: GetListResponse<TData> | null) => {
337
- if (!previous) {
338
- return null;
339
- }
342
+ const data = previous.data.map(
343
+ (record: TData) => {
344
+ if (
345
+ record.id?.toString() ===
346
+ id?.toString()
347
+ ) {
348
+ return {
349
+ id,
350
+ ...record,
351
+ ...values,
352
+ } as unknown as TData;
353
+ }
354
+ return record;
355
+ },
356
+ );
357
+
358
+ return {
359
+ ...previous,
360
+ data,
361
+ };
362
+ },
363
+ );
364
+ }
340
365
 
341
- const data = previous.data.map((record: TData) => {
342
- if (record.id?.toString() === id?.toString()) {
343
- record = {
366
+ if (optimisticUpdateMap.many) {
367
+ queryClient.setQueriesData(
368
+ resourceKeys.action("many").get(preferLegacyKeys),
369
+ (previous?: GetManyResponse<TData> | null) => {
370
+ if (
371
+ typeof optimisticUpdateMap.many ===
372
+ "function"
373
+ ) {
374
+ return optimisticUpdateMap.many(
375
+ previous,
376
+ values,
344
377
  id,
345
- ...record,
346
- ...values,
347
- } as unknown as TData;
378
+ );
348
379
  }
349
- return record;
350
- });
351
- return {
352
- ...previous,
353
- data,
354
- };
355
- },
356
- );
357
380
 
358
- queryClient.setQueriesData(
359
- resourceKeys
360
- .action("one")
361
- .id(id)
362
- .params(preferredMeta ?? {})
363
- .get(preferLegacyKeys),
364
- (previous?: GetListResponse<TData> | null) => {
365
- if (!previous) {
366
- return null;
367
- }
368
-
369
- return {
370
- ...previous,
371
- data: {
372
- ...previous.data,
373
- ...values,
374
- },
375
- };
376
- },
377
- );
381
+ if (!previous) {
382
+ return null;
383
+ }
384
+
385
+ const data = previous.data.map(
386
+ (record: TData) => {
387
+ if (
388
+ record.id?.toString() ===
389
+ id?.toString()
390
+ ) {
391
+ record = {
392
+ id,
393
+ ...record,
394
+ ...values,
395
+ } as unknown as TData;
396
+ }
397
+ return record;
398
+ },
399
+ );
400
+ return {
401
+ ...previous,
402
+ data,
403
+ };
404
+ },
405
+ );
406
+ }
407
+
408
+ if (optimisticUpdateMap.detail) {
409
+ queryClient.setQueriesData(
410
+ resourceKeys
411
+ .action("one")
412
+ .id(id)
413
+ .params(preferredMeta ?? {})
414
+ .get(preferLegacyKeys),
415
+ (previous?: GetOneResponse<TData> | null) => {
416
+ if (
417
+ typeof optimisticUpdateMap.detail ===
418
+ "function"
419
+ ) {
420
+ return optimisticUpdateMap.detail(
421
+ previous,
422
+ values,
423
+ id,
424
+ );
425
+ }
426
+
427
+ if (!previous) {
428
+ return null;
429
+ }
430
+
431
+ return {
432
+ ...previous,
433
+ data: {
434
+ ...previous.data,
435
+ ...values,
436
+ },
437
+ };
438
+ },
439
+ );
440
+ }
378
441
  }
379
442
 
380
443
  return {
@@ -32,6 +32,9 @@ import {
32
32
  MetaQuery,
33
33
  GetListResponse,
34
34
  IQueryKeys,
35
+ OptimisticUpdateManyMapType,
36
+ GetManyResponse,
37
+ GetOneResponse,
35
38
  } from "../../interfaces";
36
39
  import {
37
40
  queryKeysReplacement,
@@ -90,6 +93,15 @@ type UpdateManyParams<TData, TError, TVariables> = {
90
93
  * You can use it to manage the invalidations that will occur at the end of the mutation.
91
94
  */
92
95
  invalidates?: Array<keyof IQueryKeys>;
96
+ /**
97
+ * You can use it to manage the invalidations that will occur at the end of the mutation.
98
+ * @default {
99
+ * list: true,
100
+ * many: true,
101
+ * detail: true,
102
+ * }
103
+ */
104
+ optimisticUpdateMap?: OptimisticUpdateManyMapType<TData, TVariables>;
93
105
  } & SuccessErrorNotification<
94
106
  UpdateManyResponse<TData>,
95
107
  TError,
@@ -274,8 +286,10 @@ export const useUpdateMany = <
274
286
  dataProviderName,
275
287
  meta,
276
288
  metaData,
289
+ optimisticUpdateMap = { list: true, many: true, detail: true },
277
290
  }) => {
278
291
  const { identifier } = select(resourceName);
292
+ const preferredMeta = pickNotDeprecated(meta, metaData);
279
293
 
280
294
  const queryKey = queryKeysReplacement(preferLegacyKeys)(
281
295
  identifier,
@@ -309,86 +323,96 @@ export const useUpdateMany = <
309
323
  >(resourceKeys.get(preferLegacyKeys));
310
324
 
311
325
  if (mutationModePropOrContext !== "pessimistic") {
312
- // Set the previous queries to the new ones:
313
- queryClient.setQueriesData(
314
- resourceKeys
315
- .action("list")
316
- .params(pickNotDeprecated(meta, metaData) ?? {})
317
- .get(preferLegacyKeys),
318
- (previous?: GetListResponse<TData> | null) => {
319
- if (!previous) {
320
- return null;
321
- }
322
-
323
- const data = previous.data.map((record: TData) => {
326
+ if (optimisticUpdateMap.list) {
327
+ // Set the previous queries to the new ones:
328
+ queryClient.setQueriesData(
329
+ resourceKeys
330
+ .action("list")
331
+ .params(preferredMeta ?? {})
332
+ .get(preferLegacyKeys),
333
+ (previous?: GetListResponse<TData> | null) => {
324
334
  if (
325
- record.id !== undefined &&
326
- ids
327
- .filter((id) => id !== undefined)
328
- .map(String)
329
- .includes(record.id.toString())
335
+ typeof optimisticUpdateMap.list ===
336
+ "function"
330
337
  ) {
331
- return {
332
- ...record,
333
- ...values,
334
- };
338
+ return optimisticUpdateMap.list(
339
+ previous,
340
+ values,
341
+ ids,
342
+ );
335
343
  }
336
344
 
337
- return record;
338
- });
345
+ if (!previous) {
346
+ return null;
347
+ }
339
348
 
340
- return {
341
- ...previous,
342
- data,
343
- };
344
- },
345
- );
349
+ const data = previous.data.map(
350
+ (record: TData) => {
351
+ if (
352
+ record.id !== undefined &&
353
+ ids
354
+ .filter(
355
+ (id) => id !== undefined,
356
+ )
357
+ .map(String)
358
+ .includes(record.id.toString())
359
+ ) {
360
+ return {
361
+ ...record,
362
+ ...values,
363
+ };
364
+ }
365
+
366
+ return record;
367
+ },
368
+ );
346
369
 
347
- queryClient.setQueriesData(
348
- resourceKeys.action("many").get(preferLegacyKeys),
349
- (previous?: GetListResponse<TData> | null) => {
350
- if (!previous) {
351
- return null;
352
- }
370
+ return {
371
+ ...previous,
372
+ data,
373
+ };
374
+ },
375
+ );
376
+ }
353
377
 
354
- const data = previous.data.map((record: TData) => {
378
+ if (optimisticUpdateMap.many) {
379
+ queryClient.setQueriesData(
380
+ resourceKeys.action("many").get(preferLegacyKeys),
381
+ (previous?: GetManyResponse<TData> | null) => {
355
382
  if (
356
- record.id !== undefined &&
357
- ids
358
- .filter((id) => id !== undefined)
359
- .map(String)
360
- .includes(record.id.toString())
383
+ typeof optimisticUpdateMap.many ===
384
+ "function"
361
385
  ) {
362
- return {
363
- ...record,
364
- ...values,
365
- };
386
+ return optimisticUpdateMap.many(
387
+ previous,
388
+ values,
389
+ ids,
390
+ );
366
391
  }
367
- return record;
368
- });
369
- return {
370
- ...previous,
371
- data,
372
- };
373
- },
374
- );
375
392
 
376
- for (const id of ids) {
377
- queryClient.setQueriesData(
378
- resourceKeys
379
- .action("one")
380
- .id(id)
381
- .params(pickNotDeprecated(meta, metaData))
382
- .get(preferLegacyKeys),
383
- (previous?: GetListResponse<TData> | null) => {
384
393
  if (!previous) {
385
394
  return null;
386
395
  }
387
396
 
388
- const data = {
389
- ...previous.data,
390
- ...values,
391
- };
397
+ const data = previous.data.map(
398
+ (record: TData) => {
399
+ if (
400
+ record.id !== undefined &&
401
+ ids
402
+ .filter(
403
+ (id) => id !== undefined,
404
+ )
405
+ .map(String)
406
+ .includes(record.id.toString())
407
+ ) {
408
+ return {
409
+ ...record,
410
+ ...values,
411
+ };
412
+ }
413
+ return record;
414
+ },
415
+ );
392
416
  return {
393
417
  ...previous,
394
418
  data,
@@ -396,6 +420,43 @@ export const useUpdateMany = <
396
420
  },
397
421
  );
398
422
  }
423
+
424
+ if (optimisticUpdateMap.detail) {
425
+ for (const id of ids) {
426
+ queryClient.setQueriesData(
427
+ resourceKeys
428
+ .action("one")
429
+ .id(id)
430
+ .params(preferredMeta ?? {})
431
+ .get(preferLegacyKeys),
432
+ (previous?: GetOneResponse<TData> | null) => {
433
+ if (
434
+ typeof optimisticUpdateMap.detail ===
435
+ "function"
436
+ ) {
437
+ return optimisticUpdateMap.detail(
438
+ previous,
439
+ values,
440
+ id,
441
+ );
442
+ }
443
+
444
+ if (!previous) {
445
+ return null;
446
+ }
447
+
448
+ const data = {
449
+ ...previous.data,
450
+ ...values,
451
+ };
452
+ return {
453
+ ...previous,
454
+ data,
455
+ };
456
+ },
457
+ );
458
+ }
459
+ }
399
460
  }
400
461
 
401
462
  return {
@@ -12,6 +12,7 @@ import {
12
12
  useOne,
13
13
  useRefineContext,
14
14
  useMeta,
15
+ useInvalidate,
15
16
  } from "@hooks";
16
17
 
17
18
  import {
@@ -30,6 +31,7 @@ import {
30
31
  MetaQuery,
31
32
  AutoSaveProps,
32
33
  AutoSaveReturnType,
34
+ OptimisticUpdateMapType,
33
35
  } from "../../interfaces";
34
36
  import {
35
37
  UpdateParams,
@@ -157,6 +159,15 @@ type ActionFormProps<
157
159
  TResponseError,
158
160
  TVariables
159
161
  >["mutationOptions"];
162
+ /**
163
+ * If you customize the [`optimisticUpdateMap`](https://refine.dev/docs/api-reference/core/hooks/data/useUpdateMany/#optimisticupdatemap) option, you can use it to manage the invalidations that will occur at the end of the mutation.
164
+ * @default {
165
+ * list: true,
166
+ * many: true,
167
+ * detail: true,
168
+ * }
169
+ */
170
+ optimisticUpdateMap?: OptimisticUpdateMapType<TResponse, TVariables>;
160
171
  } & SuccessErrorNotification<
161
172
  UpdateResponse<TResponse> | CreateResponse<TResponse>,
162
173
  TResponseError,
@@ -256,6 +267,7 @@ export const useForm = <
256
267
  updateMutationOptions,
257
268
  overtimeOptions,
258
269
  autoSave,
270
+ optimisticUpdateMap,
259
271
  }: UseFormProps<
260
272
  TQueryFnData,
261
273
  TError,
@@ -271,6 +283,7 @@ export const useForm = <
271
283
  TResponse,
272
284
  TResponseError
273
285
  > => {
286
+ const invalidate = useInvalidate();
274
287
  const { options } = useRefineContext();
275
288
  const getMeta = useMeta();
276
289
 
@@ -456,6 +469,22 @@ export const useForm = <
456
469
  );
457
470
  };
458
471
 
472
+ React.useEffect(() => {
473
+ return () => {
474
+ if (
475
+ autoSave?.invalidateOnUnmount &&
476
+ autoSaveMutation.status === "success"
477
+ ) {
478
+ invalidate({
479
+ id,
480
+ invalidates: invalidates || ["list", "many", "detail"],
481
+ dataProviderName,
482
+ resource: identifier,
483
+ });
484
+ }
485
+ };
486
+ }, [autoSave?.invalidateOnUnmount, autoSaveMutation.status]);
487
+
459
488
  const onFinishAutoSaveMutation = (
460
489
  values: TVariables,
461
490
  ): Promise<UpdateResponse<TResponse> | void> | void => {
@@ -471,6 +500,7 @@ export const useForm = <
471
500
  metaData: { ...combinedMeta, ...mutationMeta },
472
501
  dataProviderName,
473
502
  invalidates: [],
503
+ mutationMode: "pessimistic",
474
504
  };
475
505
 
476
506
  return autoSaveMutation.mutate(variables, {
@@ -487,13 +517,9 @@ export const useForm = <
487
517
  });
488
518
  };
489
519
 
490
- const onFinishAutoSave = React.useMemo(
491
- () =>
492
- debounce((allValues) => {
493
- return onFinishAutoSaveMutation(allValues);
494
- }, autoSave?.debounce || 1000),
495
- [],
496
- );
520
+ const onFinishAutoSave = debounce((allValues) => {
521
+ return onFinishAutoSaveMutation(allValues);
522
+ }, autoSave?.debounce || 1000);
497
523
 
498
524
  const onFinishUpdate = async (values: TVariables) => {
499
525
  setWarnWhen(false);
@@ -512,6 +538,7 @@ export const useForm = <
512
538
  metaData: { ...combinedMeta, ...mutationMeta },
513
539
  dataProviderName,
514
540
  invalidates,
541
+ optimisticUpdateMap,
515
542
  };
516
543
 
517
544
  const onSuccess = () => {
@@ -6,6 +6,8 @@ export type AutoSaveProps<TVariables> = {
6
6
  enabled: boolean;
7
7
  debounce?: number;
8
8
  onFinish?: (values: TVariables) => TVariables;
9
+ invalidateOnUnmount?: boolean;
10
+ invalidateOnClose?: boolean;
9
11
  };
10
12
  };
11
13
 
@@ -88,3 +88,5 @@ export * from "./prettify";
88
88
  export * from "./autoSave";
89
89
 
90
90
  export * from "./textTransformers";
91
+
92
+ export * from "./optimistic-update-map";