@qiaopeng/tanstack-query-plus 0.2.4 → 0.2.6

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,4 +5,5 @@ export { isDev, isProd, isTest } from "./env.js";
5
5
  export { focusManager, type FocusManagerConfig, getSmartFocusManager, pauseFocusManager, resetSmartFocusManager, resumeFocusManager, setupFocusManager, SmartFocusManager } from "./focusManager.js";
6
6
  export { areKeysEqual, containsEntity, createComplexKey, createDomainKeyFactory, createFilteredKey, createMutationKeyFactory, createPaginatedKey, createSearchKey, createSortedKey, extractEntityId, matchesKeyPattern, normalizeQueryKey, queryKeys, validateQueryKey } from "./keys.js";
7
7
  export { createAppQueryOptions, createAppQueryOptionsWithSelect } from "./queryOptions.js";
8
+ export { createListQueryOptions, type ListQueryConfig } from "./queryOptions.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,cAAc,EACd,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,cAAc,EACd,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -5,3 +5,4 @@ export { isDev, isProd, isTest } from "./env.js";
5
5
  export { focusManager, getSmartFocusManager, pauseFocusManager, resetSmartFocusManager, resumeFocusManager, setupFocusManager, SmartFocusManager } from "./focusManager.js";
6
6
  export { areKeysEqual, containsEntity, createComplexKey, createDomainKeyFactory, createFilteredKey, createMutationKeyFactory, createPaginatedKey, createSearchKey, createSortedKey, extractEntityId, matchesKeyPattern, normalizeQueryKey, queryKeys, validateQueryKey } from "./keys.js";
7
7
  export { createAppQueryOptions, createAppQueryOptionsWithSelect } from "./queryOptions.js";
8
+ export { createListQueryOptions } from "./queryOptions.js";
@@ -11,4 +11,9 @@ export interface SelectQueryConfig<TData, TSelected = TData> extends Omit<BaseQu
11
11
  select: (data: TData) => TSelected;
12
12
  }
13
13
  export declare function createAppQueryOptionsWithSelect<TData, TSelected = TData>(config: SelectQueryConfig<TData, TSelected>): UseQueryOptions<TData, DefaultError, TSelected, QueryKey>;
14
+ export interface ListQueryConfig<TData> extends Omit<BaseQueryConfig<TData>, "staleTime" | "gcTime"> {
15
+ staleTime?: number;
16
+ gcTime?: number;
17
+ }
18
+ export declare function createListQueryOptions<TData>(config: ListQueryConfig<TData>): UseQueryOptions<TData, DefaultError, TData, QueryKey>;
14
19
  //# sourceMappingURL=queryOptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryOptions.d.ts","sourceRoot":"","sources":["../../src/core/queryOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIpG,MAAM,WAAW,eAAe,CAAC,KAAK;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAalI;AAED,MAAM,WAAW,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAE,SAAQ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC1G,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC;CACpC;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,CAahL"}
1
+ {"version":3,"file":"queryOptions.d.ts","sourceRoot":"","sources":["../../src/core/queryOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIpG,MAAM,WAAW,eAAe,CAAC,KAAK;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAalI;AAED,MAAM,WAAW,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAE,SAAQ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC1G,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC;CACpC;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,CAahL;AAED,MAAM,WAAW,eAAe,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAanI"}
@@ -28,3 +28,17 @@ export function createAppQueryOptionsWithSelect(config) {
28
28
  refetchOnMount: true
29
29
  });
30
30
  }
31
+ export function createListQueryOptions(config) {
32
+ return queryOptions({
33
+ queryKey: config.queryKey,
34
+ queryFn: config.queryFn,
35
+ staleTime: config.staleTime ?? 0,
36
+ gcTime: config.gcTime ?? DEFAULT_GC_TIME,
37
+ enabled: config.enabled,
38
+ retry: defaultQueryRetryStrategy,
39
+ retryDelay: exponentialBackoff,
40
+ refetchOnWindowFocus: true,
41
+ refetchOnReconnect: true,
42
+ refetchOnMount: true
43
+ });
44
+ }
@@ -2,6 +2,7 @@ import type { MutationFunction, MutationKey, QueryClient, QueryKey, UseMutationO
2
2
  import type { MutationContext, MutationOptions } from "../types";
3
3
  import type { EntityWithId } from "../types/selectors";
4
4
  export type { MutationKey };
5
+ import { FamilySyncConfig } from "../utils/consistency.js";
5
6
  export interface MutationDefaultsConfig {
6
7
  [key: string]: TanStackUseMutationOptions<any, any, any, any>;
7
8
  }
@@ -10,11 +11,16 @@ export declare function setupMutationDefaults(queryClient: QueryClient, config:
10
11
  export declare function useListMutation<T extends EntityWithId>(mutationFn: MutationFunction<T, {
11
12
  operation: string;
12
13
  data: Partial<T>;
13
- }>, queryKey: QueryKey, options?: TanStackUseMutationOptions<T, Error, {
14
+ }>, queryKey: QueryKey, options?: (TanStackUseMutationOptions<T, Error, {
14
15
  operation: string;
15
16
  data: Partial<T>;
16
17
  }> & {
17
18
  mutationKey?: readonly unknown[];
19
+ }) & {
20
+ consistency?: {
21
+ familySync?: FamilySyncConfig;
22
+ mode?: "sync+invalidate" | "invalidate-only";
23
+ };
18
24
  }): UseMutationResult<T, Error, {
19
25
  operation: string;
20
26
  data: Partial<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../../src/hooks/useMutation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,IAAI,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACvK,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,MAAM,WAAW,sBAAsB;IAAG,CAAC,GAAG,EAAE,MAAM,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE;AAEzG,wBAAgB,WAAW,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,UAAU,GAAG,IAAI,EAAE,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAkFzN;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAEpG;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,EAAE,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE;eAAlE,MAAM;UAAQ,OAAO,CAAC,CAAC,CAAC;YAGzO;AAED,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,UAAU,GAAG,OAAO,EAAE,EAAE,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,0BAA0B,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,2DAEpP;AAED,wBAAgB,gCAAgC,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,UAAU,GAAG,IAAI,EAAE,QAAQ,GAAG,OAAO,EACrH,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,EAC/C,SAAS,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,EAC7C,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,oFAuD1H;AAED,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/I;AACD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,GAAG,IAAI,CAE/L;AACD,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvJ"}
1
+ {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../../src/hooks/useMutation.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,29 @@
1
- import { findFamilyQueries, syncEntityAcrossFamily } from "../utils/consistency.js";
2
1
  import { useQueryClient, useMutation as useTanStackMutation } from "@tanstack/react-query";
3
2
  import { DEFAULT_MUTATION_CONFIG } from "../core/config.js";
3
+ import { syncEntityAcrossFamily, DEFAULT_FAMILY_SYNC } from "../utils/consistency.js";
4
+ function deriveFamilyKey(queryKey) {
5
+ const arr = Array.isArray(queryKey) ? [...queryKey] : [queryKey];
6
+ while (arr.length > 1) {
7
+ const last = arr[arr.length - 1];
8
+ if (last && typeof last === "object" && !Array.isArray(last)) {
9
+ arr.pop();
10
+ continue;
11
+ }
12
+ if (typeof last === "string" && (last === "paginated" || last === "filtered" || last === "sorted" || last === "search" || last === "complex")) {
13
+ arr.pop();
14
+ continue;
15
+ }
16
+ break;
17
+ }
18
+ return arr;
19
+ }
20
+ function isListFamilyKey(queryKey) {
21
+ const parts = Array.isArray(queryKey) ? queryKey : [queryKey];
22
+ return parts.includes("list") || parts.includes("paginated");
23
+ }
4
24
  export function useMutation(options) {
5
25
  const queryClient = useQueryClient();
6
- const { optimistic, onMutate, onError, onSuccess, onSettled, ...restOptions } = options;
26
+ const { optimistic, onMutate, onError, onSuccess, onSettled, consistency, ...restOptions } = options;
7
27
  const mutationConfig = {
8
28
  ...restOptions,
9
29
  retry: restOptions.retry ?? DEFAULT_MUTATION_CONFIG?.retry,
@@ -32,7 +52,7 @@ export function useMutation(options) {
32
52
  return { userContext };
33
53
  }
34
54
  try {
35
- await queryClient.cancelQueries({ queryKey: optimistic.queryKey });
55
+ await queryClient.cancelQueries({ queryKey: optimistic.queryKey, exact: true });
36
56
  const previousData = queryClient.getQueryData(optimistic.queryKey);
37
57
  let mappedVariables = variables;
38
58
  if (optimistic.fieldMapping && typeof variables === "object" && variables !== null) {
@@ -70,20 +90,45 @@ export function useMutation(options) {
70
90
  }
71
91
  };
72
92
  mutationConfig.onSuccess = (data, variables, context) => {
73
- queryClient.invalidateQueries({ queryKey: optimistic.queryKey });
74
- const consistency = options.consistency;
75
- if (consistency && Array.isArray(consistency.baseKey) && consistency.baseKey.length > 0) {
76
- try {
77
- const keys = findFamilyQueries(queryClient, { baseKey: consistency.baseKey, maxKeys: consistency.maxKeys });
78
- if (consistency.mode === "sync+invalidate") {
79
- const updatedEntity = (typeof data === "object" && data !== null) ? data : (typeof variables === "object" && variables !== null ? variables : undefined);
80
- if (updatedEntity) {
81
- syncEntityAcrossFamily(queryClient, keys, updatedEntity, { idField: consistency.idField, listSelector: consistency.listSelector });
82
- }
83
- }
84
- keys.forEach((key) => { queryClient.invalidateQueries({ queryKey: key }); });
93
+ const shouldSync = (consistency?.mode ?? "sync+invalidate") === "sync+invalidate";
94
+ if (shouldSync && optimistic?.queryKey) {
95
+ const familyKey = optimistic.familyKey ?? deriveFamilyKey(optimistic.queryKey);
96
+ const payload = typeof variables === "object" && variables !== null ? (variables.data ?? variables) : variables;
97
+ const op = typeof variables?.operation === "string" ? variables.operation : "update";
98
+ const cfg = consistency?.familySync ?? DEFAULT_FAMILY_SYNC;
99
+ syncEntityAcrossFamily(queryClient, familyKey, cfg, op, payload);
100
+ }
101
+ const scope = optimistic.invalidateScope ?? (isListFamilyKey(optimistic.queryKey) ? "family" : "exact");
102
+ const invalidations = [];
103
+ if (scope !== "none") {
104
+ if (scope === "family") {
105
+ const familyKey = optimistic.familyKey ?? deriveFamilyKey(optimistic.queryKey);
106
+ invalidations.push({ queryKey: familyKey });
107
+ }
108
+ else {
109
+ invalidations.push({ queryKey: optimistic.queryKey });
110
+ }
111
+ }
112
+ if (Array.isArray(optimistic.relatedKeys) && optimistic.relatedKeys.length > 0) {
113
+ optimistic.relatedKeys.forEach((k) => invalidations.push({ queryKey: k }));
114
+ }
115
+ if (invalidations.length > 0) {
116
+ const seen = new Set();
117
+ const tasks = invalidations
118
+ .map((cfg) => ({ ...cfg, exact: false }))
119
+ .filter((cfg) => {
120
+ const key = JSON.stringify(cfg.queryKey);
121
+ if (seen.has(key))
122
+ return false;
123
+ seen.add(key);
124
+ return true;
125
+ });
126
+ if (tasks.length === 1) {
127
+ queryClient.invalidateQueries(tasks[0]);
128
+ }
129
+ else if (tasks.length > 1) {
130
+ invalidateQueriesBatch(queryClient, tasks);
85
131
  }
86
- catch { }
87
132
  }
88
133
  if (onSuccess) {
89
134
  const successCallback = onSuccess;
@@ -104,7 +149,23 @@ export function setupMutationDefaults(queryClient, config) {
104
149
  }
105
150
  export function useListMutation(mutationFn, queryKey, options) {
106
151
  const queryClient = useQueryClient();
107
- return useTanStackMutation({ mutationFn, onSettled: () => { queryClient.invalidateQueries({ queryKey }); }, ...options, mutationKey: options?.mutationKey });
152
+ return useTanStackMutation({
153
+ mutationFn,
154
+ onSuccess: (_data, variables) => {
155
+ const mode = options?.consistency?.mode ?? "sync+invalidate";
156
+ if (mode === "sync+invalidate") {
157
+ const familyKey = deriveFamilyKey(queryKey);
158
+ const cfg = options?.consistency?.familySync ?? DEFAULT_FAMILY_SYNC;
159
+ syncEntityAcrossFamily(queryClient, familyKey, cfg, variables.operation, variables.data);
160
+ }
161
+ },
162
+ onSettled: () => {
163
+ const familyKey = deriveFamilyKey(queryKey);
164
+ queryClient.invalidateQueries({ queryKey: familyKey, exact: false });
165
+ },
166
+ ...options,
167
+ mutationKey: options?.mutationKey
168
+ });
108
169
  }
109
170
  export function useBatchMutation(mutationFn, options) {
110
171
  return useTanStackMutation({ mutationFn, ...options, mutationKey: options?.mutationKey });
@@ -122,7 +183,7 @@ export function useConditionalOptimisticMutation(mutationFn, condition, options)
122
183
  return { userContext, conditionMet: false };
123
184
  }
124
185
  try {
125
- await queryClient.cancelQueries({ queryKey: optimistic.queryKey });
186
+ await queryClient.cancelQueries({ queryKey: optimistic.queryKey, exact: true });
126
187
  const previousData = queryClient.getQueryData(optimistic.queryKey);
127
188
  queryClient.setQueryData(optimistic.queryKey, (oldData) => optimistic.updater(oldData, variables));
128
189
  const mutateCallback = onMutate;
@@ -156,7 +217,38 @@ export function useConditionalOptimisticMutation(mutationFn, condition, options)
156
217
  };
157
218
  mutationConfig.onSettled = (data, error, variables, context) => {
158
219
  if (context?.conditionMet) {
159
- queryClient.invalidateQueries({ queryKey: optimistic.queryKey });
220
+ const scope = optimistic.invalidateScope ?? (isListFamilyKey(optimistic.queryKey) ? "family" : "exact");
221
+ const invalidations = [];
222
+ if (scope !== "none") {
223
+ if (scope === "family") {
224
+ const familyKey = optimistic.familyKey ?? deriveFamilyKey(optimistic.queryKey);
225
+ invalidations.push({ queryKey: familyKey });
226
+ }
227
+ else {
228
+ invalidations.push({ queryKey: optimistic.queryKey });
229
+ }
230
+ }
231
+ if (Array.isArray(optimistic.relatedKeys) && optimistic.relatedKeys.length > 0) {
232
+ optimistic.relatedKeys.forEach((k) => invalidations.push({ queryKey: k }));
233
+ }
234
+ if (invalidations.length > 0) {
235
+ const seen = new Set();
236
+ const tasks = invalidations
237
+ .map((cfg) => ({ ...cfg, exact: false }))
238
+ .filter((cfg) => {
239
+ const key = JSON.stringify(cfg.queryKey);
240
+ if (seen.has(key))
241
+ return false;
242
+ seen.add(key);
243
+ return true;
244
+ });
245
+ if (tasks.length === 1) {
246
+ queryClient.invalidateQueries(tasks[0]);
247
+ }
248
+ else if (tasks.length > 1) {
249
+ invalidateQueriesBatch(queryClient, tasks);
250
+ }
251
+ }
160
252
  }
161
253
  if (onSettled) {
162
254
  const settledCallback = onSettled;
@@ -6,7 +6,6 @@ export * from "./optimistic.js";
6
6
  export * from "./persistence.js";
7
7
  export * from "./selectors.js";
8
8
  export * from "./suspense.js";
9
- export * from "./consistency.js";
10
9
  export interface MutationContext<TData = unknown, TContext = unknown> {
11
10
  previousData?: TData;
12
11
  userContext?: TContext;
@@ -19,16 +18,22 @@ export interface MutationOptions<TData, TError, TVariables, TContext = unknown>
19
18
  enabled?: boolean;
20
19
  fieldMapping?: Record<string, string>;
21
20
  rollback?: <TQueryData = unknown>(previousData: TQueryData, error: Error) => void;
21
+ invalidateScope?: "none" | "exact" | "family";
22
+ familyKey?: QueryKey;
23
+ relatedKeys?: QueryKey[];
22
24
  };
23
25
  consistency?: {
24
- baseKey: QueryKey;
25
- mode?: "invalidate" | "sync+invalidate";
26
- idField?: string;
27
- listSelector?: (data: unknown) => unknown[] | {
28
- items: unknown[];
29
- total?: number;
30
- } | null;
31
- maxKeys?: number;
26
+ familySync?: {
27
+ idField?: string;
28
+ listSelector?: (data: unknown) => {
29
+ items: unknown[];
30
+ total?: number;
31
+ } | null;
32
+ writeBack?: (old: unknown, items: unknown[], total?: number) => unknown;
33
+ maxKeys?: number;
34
+ enableForOperations?: Array<"update" | "delete">;
35
+ };
36
+ mode?: "sync+invalidate" | "invalidate-only";
32
37
  };
33
38
  }
34
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,MAAM,WAAW,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,GAAG,OAAO;IAAI,YAAY,CAAC,EAAE,KAAK,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE;AAC9I,MAAM,WAAW,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAE,SAAQ,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC7I,UAAU,CAAC,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,SAAS,EAAE,UAAU,KAAK,UAAU,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,GAAG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAAE,CAAC;IACpS,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,YAAY,GAAG,iBAAiB,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,EAAE,GAAG;YAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7M"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,MAAM,WAAW,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,GAAG,OAAO;IAAI,YAAY,CAAC,EAAE,KAAK,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE;AAC9I,MAAM,WAAW,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAE,SAAQ,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC7I,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,QAAQ,CAAC;QACnB,OAAO,EAAE,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,SAAS,EAAE,UAAU,KAAK,UAAU,GAAG,SAAS,CAAC;QAClH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,QAAQ,CAAC,EAAE,CAAC,UAAU,GAAG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;QAClF,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;QAC9C,SAAS,CAAC,EAAE,QAAQ,CAAC;QACrB,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC;KAC1B,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK;gBAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAC;YAC9E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;YACxE,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,mBAAmB,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;SAClD,CAAC;QACF,IAAI,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAAC;KAC9C,CAAC;CACH"}
@@ -5,4 +5,3 @@ export * from "./optimistic.js";
5
5
  export * from "./persistence.js";
6
6
  export * from "./selectors.js";
7
7
  export * from "./suspense.js";
8
- export * from "./consistency.js";
@@ -1,14 +1,16 @@
1
1
  import type { QueryClient, QueryKey } from "@tanstack/react-query";
2
- export interface FamilyQueryMatchOptions {
3
- baseKey: QueryKey;
4
- maxKeys?: number;
5
- }
6
- export declare function findFamilyQueries(queryClient: QueryClient, options: FamilyQueryMatchOptions): QueryKey[];
7
- export declare function syncEntityAcrossFamily(queryClient: QueryClient, keys: QueryKey[], updatedEntity: unknown, options: {
2
+ import type { EntityWithId } from "../types/selectors";
3
+ export declare function startsWithKeyPrefix(key: QueryKey, prefix: QueryKey): boolean;
4
+ export type FamilySyncConfig = {
8
5
  idField?: string;
9
- listSelector?: (data: unknown) => unknown[] | {
10
- items: unknown[];
6
+ listSelector?: (data: unknown) => {
7
+ items: EntityWithId[];
11
8
  total?: number;
12
9
  } | null;
13
- }): void;
10
+ writeBack?: (old: unknown, items: EntityWithId[], total?: number) => unknown;
11
+ maxKeys?: number;
12
+ enableForOperations?: Array<"update" | "delete">;
13
+ };
14
+ export declare const DEFAULT_FAMILY_SYNC: FamilySyncConfig;
15
+ export declare function syncEntityAcrossFamily(queryClient: QueryClient, familyPrefix: QueryKey, cfg: FamilySyncConfig, operation: string, payload: Partial<EntityWithId>): void;
14
16
  //# sourceMappingURL=consistency.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consistency.d.ts","sourceRoot":"","sources":["../../src/utils/consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEnE,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,QAAQ,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,GAAG,QAAQ,EAAE,CAQxG;AAeD,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,EAAE,GAAG;QAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CA6BzO"}
1
+ {"version":3,"file":"consistency.d.ts","sourceRoot":"","sources":["../../src/utils/consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAA2O;AACxT,MAAM,MAAM,gBAAgB,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK;QAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAA;CAAE,CAAC;AA2B1R,eAAO,MAAM,mBAAmB,EAAE,gBAA4J,CAAC;AAC/L,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAqBvK"}
@@ -1,68 +1,79 @@
1
- function isObjectEqual(a, b) {
2
- if (typeof a === "object" && a !== null && typeof b === "object" && b !== null) {
1
+ import { listUpdater } from "./optimisticUtils.js";
2
+ function ensureArray(key) { return Array.isArray(key) ? key : [key]; }
3
+ function deepEqual(a, b) { if (a === b)
4
+ return true; if (typeof a === "object" && a !== null && typeof b === "object" && b !== null) {
5
+ try {
3
6
  return JSON.stringify(a) === JSON.stringify(b);
4
7
  }
5
- return a === b;
6
- }
7
- function startsWithKey(key, prefix) {
8
- if (prefix.length > key.length)
8
+ catch {
9
9
  return false;
10
- for (let i = 0; i < prefix.length; i++) {
11
- if (!isObjectEqual(key[i], prefix[i]))
12
- return false;
13
10
  }
14
- return true;
15
- }
16
- export function findFamilyQueries(queryClient, options) {
17
- const { baseKey, maxKeys } = options;
18
- const queries = queryClient.getQueryCache().findAll({ predicate: (q) => startsWithKey(q.queryKey, baseKey) });
19
- const keys = queries.map((q) => q.queryKey);
20
- if (typeof maxKeys === "number" && maxKeys > 0) {
21
- return keys.slice(0, maxKeys);
11
+ } return false; }
12
+ export function startsWithKeyPrefix(key, prefix) { const k = ensureArray(key); const p = ensureArray(prefix); if (p.length > k.length)
13
+ return false; for (let i = 0; i < p.length; i++) {
14
+ const a = k[i];
15
+ const b = p[i];
16
+ if (!(a === b || deepEqual(a, b)))
17
+ return false;
18
+ } return true; }
19
+ function defaultListSelector(data) {
20
+ if (!data)
21
+ return null;
22
+ if (Array.isArray(data))
23
+ return { items: data };
24
+ if (typeof data === "object") {
25
+ const obj = data;
26
+ if (Array.isArray(obj.items))
27
+ return { items: obj.items, total: typeof obj.total === "number" ? obj.total : undefined };
28
+ if (Array.isArray(obj.Rows))
29
+ return { items: obj.Rows, total: typeof obj.Total === "number" ? obj.Total : undefined };
22
30
  }
23
- return keys;
31
+ return null;
24
32
  }
25
- function updateArrayById(items, updated, idField) {
26
- const list = Array.isArray(items) ? items : [];
27
- const id = updated[idField];
28
- if (id === undefined)
29
- return list;
30
- return list.map((item) => {
31
- const currentId = item[idField];
32
- if (currentId === id) {
33
- return { ...item, ...updated };
33
+ function defaultWriteBack(old, items, total) {
34
+ if (old && typeof old === "object") {
35
+ const obj = { ...old };
36
+ if (Array.isArray(obj.Rows)) {
37
+ obj.Rows = items;
38
+ if (typeof total !== "undefined")
39
+ obj.Total = total;
40
+ return obj;
34
41
  }
35
- return item;
36
- });
42
+ if (Array.isArray(obj.items)) {
43
+ obj.items = items;
44
+ if (typeof total !== "undefined")
45
+ obj.total = total;
46
+ return obj;
47
+ }
48
+ }
49
+ return { items, total };
37
50
  }
38
- export function syncEntityAcrossFamily(queryClient, keys, updatedEntity, options) {
39
- const idField = options.idField ?? "id";
40
- keys.forEach((key) => {
41
- const oldData = queryClient.getQueryData(key);
42
- if (Array.isArray(oldData)) {
43
- const next = updateArrayById(oldData, updatedEntity, idField);
44
- queryClient.setQueryData(key, next);
51
+ export const DEFAULT_FAMILY_SYNC = { idField: "id", listSelector: defaultListSelector, writeBack: defaultWriteBack, maxKeys: 50, enableForOperations: ["update", "delete"] };
52
+ export function syncEntityAcrossFamily(queryClient, familyPrefix, cfg, operation, payload) {
53
+ const enabledOps = cfg.enableForOperations ?? ["update", "delete"];
54
+ const op = String(operation).toLowerCase();
55
+ if (!enabledOps.includes(op))
56
+ return;
57
+ const idField = cfg.idField ?? "id";
58
+ const cache = queryClient.getQueryCache();
59
+ const queries = cache.findAll({ predicate: (q) => startsWithKeyPrefix(q.queryKey, familyPrefix) });
60
+ const limited = typeof cfg.maxKeys === "number" && cfg.maxKeys > 0 ? queries.slice(0, cfg.maxKeys) : queries;
61
+ limited.forEach((q) => {
62
+ const key = q.queryKey;
63
+ const old = queryClient.getQueryData(key);
64
+ const picked = (cfg.listSelector ?? defaultListSelector)(old);
65
+ if (!picked || !Array.isArray(picked.items))
45
66
  return;
67
+ const idValue = payload?.[idField];
68
+ let items = picked.items;
69
+ if (op === "update" && idValue !== undefined) {
70
+ items = listUpdater.update(items, { ...payload, id: idValue });
46
71
  }
47
- if (oldData && typeof oldData === "object") {
48
- const selector = options.listSelector;
49
- if (selector) {
50
- const selected = selector(oldData);
51
- if (selected === null)
52
- return;
53
- if (selected && Array.isArray(selected.items)) {
54
- const nextItems = updateArrayById(selected.items, updatedEntity, idField);
55
- const next = { ...oldData, items: nextItems };
56
- queryClient.setQueryData(key, next);
57
- return;
58
- }
59
- }
60
- if (Object.prototype.hasOwnProperty.call(oldData, "items")) {
61
- const items = oldData["items"];
62
- const nextItems = updateArrayById(items, updatedEntity, idField);
63
- const next = { ...oldData, items: nextItems };
64
- queryClient.setQueryData(key, next);
65
- }
72
+ else if (op === "delete" && idValue !== undefined) {
73
+ items = listUpdater.remove(items, idValue);
66
74
  }
75
+ const total = typeof picked.total === "number" && op === "delete" ? Math.max(0, picked.total - 1) : picked.total;
76
+ const next = (cfg.writeBack ?? defaultWriteBack)(old, items, total);
77
+ queryClient.setQueryData(key, next);
67
78
  });
68
79
  }
@@ -6,5 +6,5 @@ export { getPrefetchManager, type InteractionRecord, type NetworkSpeed, type Pre
6
6
  export { createQueryKeyFactory, createSimpleQueryKeyFactory, extractParamsFromKey, isQueryKeyEqual, type NormalizeConfig, normalizeQueryParams, type QueryKeyFactory, type QueryKeyFactoryConfig } from "./queryKey.js";
7
7
  export { compose, selectById, selectByIds, selectCount, selectField, selectFields, selectFirst, selectItems, selectLast, selectMap, selectors, selectTotal, selectWhere } from "./selectors.js";
8
8
  export { deepClone, formatBytes, getStorageUsage, isStorageAvailable } from "./storage.js";
9
- export { findFamilyQueries, syncEntityAcrossFamily, type FamilyQueryMatchOptions } from "./consistency.js";
9
+ export { startsWithKeyPrefix, syncEntityAcrossFamily, DEFAULT_FAMILY_SYNC, type FamilySyncConfig } from "./consistency.js";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC3H,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1P,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACpO,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACxN,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC3H,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1P,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACpO,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACxN,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -6,4 +6,4 @@ export { getPrefetchManager, resetPrefetchManager, SmartPrefetchManager } from "
6
6
  export { createQueryKeyFactory, createSimpleQueryKeyFactory, extractParamsFromKey, isQueryKeyEqual, normalizeQueryParams } from "./queryKey.js";
7
7
  export { compose, selectById, selectByIds, selectCount, selectField, selectFields, selectFirst, selectItems, selectLast, selectMap, selectors, selectTotal, selectWhere } from "./selectors.js";
8
8
  export { deepClone, formatBytes, getStorageUsage, isStorageAvailable } from "./storage.js";
9
- export { findFamilyQueries, syncEntityAcrossFamily } from "./consistency.js";
9
+ export { startsWithKeyPrefix, syncEntityAcrossFamily, DEFAULT_FAMILY_SYNC } from "./consistency.js";
@@ -31,4 +31,11 @@ export declare function batchUpdateItems<T extends EntityWithId>(items: T[] | un
31
31
  export declare function batchRemoveItems<T extends EntityWithId>(items: T[] | undefined | null, itemIds: Array<T["id"]>): T[];
32
32
  export declare function reorderItems<T extends EntityWithId>(items: T[] | undefined | null, fromIndex: number, toIndex: number): T[];
33
33
  export declare function conditionalUpdateItems<T extends EntityWithId>(items: T[] | undefined | null, predicate: (item: T) => boolean, updater: (item: T) => Partial<T>): T[];
34
+ export declare function applyListOperationToPaginated<T extends EntityWithId>(data: {
35
+ items: T[];
36
+ total?: number;
37
+ }, operation: ListOperationType, payload: Partial<T>): {
38
+ items: T[];
39
+ total?: number;
40
+ };
34
41
  //# sourceMappingURL=optimisticUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimisticUtils.d.ts","sourceRoot":"","sources":["../../src/utils/optimisticUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"optimisticUtils.d.ts","sourceRoot":"","sources":["../../src/utils/optimisticUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAgC,MAAM,qBAAqB,CAAC;AACrH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,eAAO,MAAM,WAAW;UAChB,CAAC,SAAS,YAAY,SAAS,CAAC,EAAE,GAAG,SAAS,WAAW,CAAC,KAAG,CAAC,EAAE;aAU7D,CAAC,SAAS,YAAY,SAAS,CAAC,EAAE,GAAG,SAAS,eAAe,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;KAAE,KAAG,CAAC,EAAE;aAI/F,CAAC,SAAS,YAAY,SAAS,CAAC,EAAE,GAAG,SAAS,UAAU,CAAC,CAAC,IAAI,CAAC,KAAG,CAAC,EAAE;CAI/E,CAAC;AACF,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CAAE,GAAG,sBAAsB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAErL;AACD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CAAE,GAAG,sBAAsB,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAE/L;AACD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CAAE,GAAG,sBAAsB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAE1K;AACD,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,YAAY,EAAE,UAAU,SAAS,iBAAiB,IAAI,UAAU,SAAS,iBAAiB,CAAC,GAAG,GAAG,CAAC,GAAG,UAAU,SAAS,iBAAiB,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,UAAU,SAAS,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;AAC7R,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,YAAY,EAAE,UAAU,SAAS,iBAAiB,GAAG,iBAAiB,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CA2B9N;AACD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,GAAG,CAAC,EAAE,CAIzI;AACD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAIpH;AACD,wBAAgB,YAAY,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,CAM3H;AACD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAGpK;AACD,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,YAAY,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAa7L"}
@@ -45,7 +45,16 @@ export function createListOperationConfig(config) {
45
45
  return oldData || [];
46
46
  }
47
47
  },
48
- rollback: config.onRollback ? (previousData, error) => { config.onRollback(error, { previousData, timestamp: Date.now(), operationType: "update" }); } : undefined,
48
+ rollback: config.onRollback
49
+ ? (previousData, error) => {
50
+ const opType = config.operation === ListOperationType.ADD
51
+ ? "create"
52
+ : config.operation === ListOperationType.REMOVE
53
+ ? "delete"
54
+ : "update";
55
+ config.onRollback(error, { previousData, timestamp: Date.now(), operationType: opType });
56
+ }
57
+ : undefined,
49
58
  enabled: true
50
59
  };
51
60
  }
@@ -74,3 +83,24 @@ export function conditionalUpdateItems(items, predicate, updater) {
74
83
  return { ...item, ...updater(item) };
75
84
  } return item; });
76
85
  }
86
+ export function applyListOperationToPaginated(data, operation, payload) {
87
+ let items = data.items || [];
88
+ if (operation === ListOperationType.ADD) {
89
+ items = listUpdater.add(items, payload);
90
+ }
91
+ else if (operation === ListOperationType.UPDATE) {
92
+ items = listUpdater.update(items, payload);
93
+ }
94
+ else if (operation === ListOperationType.REMOVE) {
95
+ const id = payload?.id;
96
+ items = listUpdater.remove(items, id);
97
+ }
98
+ const total = typeof data.total === "number"
99
+ ? operation === ListOperationType.ADD
100
+ ? data.total + 1
101
+ : operation === ListOperationType.REMOVE
102
+ ? Math.max(0, data.total - 1)
103
+ : data.total
104
+ : data.total;
105
+ return { ...data, items, total };
106
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qiaopeng/tanstack-query-plus",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Enhanced TanStack Query toolkit: defaults, hooks, persistence, offline, utils",
5
5
  "author": "qiaopeng",
6
6
  "license": "MIT",