@qiaopeng/tanstack-query-plus 0.2.13 → 0.2.14
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/README.md +18 -16
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useMutation.d.ts +0 -6
- package/dist/hooks/useMutation.d.ts.map +1 -1
- package/dist/hooks/useMutation.js +0 -38
- package/dist/utils/consistency.d.ts.map +1 -1
- package/dist/utils/consistency.js +1 -21
- package/dist/utils/optimisticUtils.d.ts +4 -0
- package/dist/utils/optimisticUtils.d.ts.map +1 -1
- package/dist/utils/optimisticUtils.js +13 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1046,10 +1046,10 @@ function TodoApp() {
|
|
|
1046
1046
|
|
|
1047
1047
|
在带分页/筛选/排序的列表中,编辑、新增、删除、状态变更成功后切换 `page/pageSize` 时,可能命中同一资源的另一查询变体,从而短暂显示旧快照。本库提供可选的“家族一致性”能力,保障在成功后切换分页不回退。
|
|
1048
1048
|
|
|
1049
|
-
- 开启方式:在 `useMutation` 传入 `consistency`
|
|
1050
|
-
-
|
|
1051
|
-
-
|
|
1052
|
-
- 形状适配:通过 `listSelector` 适配 `{items,total}` 结构;无法识别时自动降级为仅失效
|
|
1049
|
+
- 开启方式:在 `useMutation` 传入 `consistency` 配置
|
|
1050
|
+
- 默认策略:`mode: 'sync+invalidate'` 先同步更新缓存,再延迟失效,确保 UI 立即响应且最终一致
|
|
1051
|
+
- 安全策略:`mode: 'invalidate-only'` 仅执行失效,完全依赖服务端数据(适合非关键数据)
|
|
1052
|
+
- 形状适配:通过 `consistency.familySync.listSelector` 适配 `{items,total}` 结构;无法识别时自动降级为仅失效
|
|
1053
1053
|
|
|
1054
1054
|
```tsx
|
|
1055
1055
|
import { useMutation } from '@qiaopeng/tanstack-query-plus/hooks'
|
|
@@ -1067,18 +1067,20 @@ function useUpdateProduct({ page, pageSize }) {
|
|
|
1067
1067
|
|
|
1068
1068
|
// 家族一致性:编辑成功后,保障跨分页/筛选/排序的变体不回退
|
|
1069
1069
|
consistency: {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1070
|
+
mode: 'sync+invalidate', // 默认值,先同步缓存再延迟失效
|
|
1071
|
+
invalidationDelay: 1000, // 延迟失效,等待后端一致性
|
|
1072
|
+
familySync: {
|
|
1073
|
+
idField: 'id',
|
|
1074
|
+
// 适配分页对象:提取 items;不确定时返回 null 将仅失效
|
|
1075
|
+
listSelector: (data) => {
|
|
1076
|
+
if (data && typeof data === 'object' && 'items' in (data as any)) {
|
|
1077
|
+
return { items: (data as any).items, total: (data as any).total }
|
|
1078
|
+
}
|
|
1079
|
+
if (Array.isArray(data)) return { items: data }
|
|
1080
|
+
return null
|
|
1081
|
+
},
|
|
1082
|
+
maxKeys: 50,
|
|
1083
|
+
}
|
|
1082
1084
|
},
|
|
1083
1085
|
})
|
|
1084
1086
|
}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { batchQueryUtils, calculateBatchStats, createBatchQueryConfig, useAutoRefreshBatchQueries, useBatchQueryPerformance, useCombinedQueries, useConditionalBatchQueries, useDashboardQueries, useDependentBatchQueries, useDynamicBatchQueries, useEnhancedQueries, useEnhancedSuspenseQueries, usePaginatedBatchQueries, useRetryBatchQueries } from "./batchQueries.js";
|
|
2
2
|
export { useConditionalFocusRefetch, useFocusCallback, useFocusRefetch, type UseFocusRefetchOptions, useFocusState, usePageVisibility, usePauseFocus, type UsePauseFocusOptions, useSmartFocusManager } from "./useFocusManager.js";
|
|
3
3
|
export { createCursorPaginationOptions, createInfiniteQueryOptions, createOffsetPaginationOptions, createPageNumberPaginationOptions, useEnhancedInfiniteQuery } from "./useInfiniteQuery.js";
|
|
4
|
-
export { cancelQueriesBatch, invalidateQueriesBatch, type MutationDefaultsConfig, type MutationKey, setQueryDataBatch, setupMutationDefaults,
|
|
4
|
+
export { cancelQueriesBatch, invalidateQueriesBatch, type MutationDefaultsConfig, type MutationKey, setQueryDataBatch, setupMutationDefaults, useListMutation, useMutation } from "./useMutation.js";
|
|
5
5
|
export { type HoverPrefetchOptions, type InViewPrefetchOptions, type PrefetchOptions, useBatchPrefetch, useConditionalPrefetch, useHoverPrefetch, useIdlePrefetch, usePeriodicPrefetch, usePredictivePrefetch, usePriorityPrefetch, useRoutePrefetch, useSmartPrefetch } from "./usePrefetch.js";
|
|
6
6
|
export { skipToken, useEnhancedQuery, type EnhancedQueryOptions, type EnhancedQueryResult } from "./useQuery.js";
|
|
7
7
|
export { createSuspenseInfiniteQuery, createSuspenseQuery, useEnhancedSuspenseInfiniteQuery, useEnhancedSuspenseQuery } from "./useSuspenseQuery.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EACf,KAAK,sBAAsB,EAC3B,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,KAAK,oBAAoB,EACzB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC9L,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EACf,KAAK,sBAAsB,EAC3B,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,KAAK,oBAAoB,EACzB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC9L,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { batchQueryUtils, calculateBatchStats, createBatchQueryConfig, useAutoRefreshBatchQueries, useBatchQueryPerformance, useCombinedQueries, useConditionalBatchQueries, useDashboardQueries, useDependentBatchQueries, useDynamicBatchQueries, useEnhancedQueries, useEnhancedSuspenseQueries, usePaginatedBatchQueries, useRetryBatchQueries } from "./batchQueries.js";
|
|
2
2
|
export { useConditionalFocusRefetch, useFocusCallback, useFocusRefetch, useFocusState, usePageVisibility, usePauseFocus, useSmartFocusManager } from "./useFocusManager.js";
|
|
3
3
|
export { createCursorPaginationOptions, createInfiniteQueryOptions, createOffsetPaginationOptions, createPageNumberPaginationOptions, useEnhancedInfiniteQuery } from "./useInfiniteQuery.js";
|
|
4
|
-
export { cancelQueriesBatch, invalidateQueriesBatch, setQueryDataBatch, setupMutationDefaults,
|
|
4
|
+
export { cancelQueriesBatch, invalidateQueriesBatch, setQueryDataBatch, setupMutationDefaults, useListMutation, useMutation } from "./useMutation.js";
|
|
5
5
|
export { useBatchPrefetch, useConditionalPrefetch, useHoverPrefetch, useIdlePrefetch, usePeriodicPrefetch, usePredictivePrefetch, usePriorityPrefetch, useRoutePrefetch, useSmartPrefetch } from "./usePrefetch.js";
|
|
6
6
|
export { skipToken, useEnhancedQuery } from "./useQuery.js";
|
|
7
7
|
export { createSuspenseInfiniteQuery, createSuspenseQuery, useEnhancedSuspenseInfiniteQuery, useEnhancedSuspenseQuery } from "./useSuspenseQuery.js";
|
|
@@ -29,10 +29,4 @@ export declare function useListMutation<T extends EntityWithId>(mutationFn: Muta
|
|
|
29
29
|
operation: string;
|
|
30
30
|
data: Partial<T>;
|
|
31
31
|
}, unknown>;
|
|
32
|
-
export declare function useBatchMutation<TData = unknown, TError = Error, TVariables = unknown[]>(mutationFn: MutationFunction<TData[], TVariables>, options?: TanStackUseMutationOptions<TData[], TError, TVariables> & {
|
|
33
|
-
mutationKey?: readonly unknown[];
|
|
34
|
-
}): UseMutationResult<TData[], TError, TVariables, unknown>;
|
|
35
|
-
export declare function useConditionalOptimisticMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(mutationFn: MutationFunction<TData, TVariables>, condition: (variables: TVariables) => boolean, options?: Omit<MutationOptions<TData, TError, TVariables, TContext>, "mutationFn"> & {
|
|
36
|
-
mutationKey?: readonly unknown[];
|
|
37
|
-
}): UseMutationResult<TData, TError, TVariables, TContext>;
|
|
38
32
|
//# sourceMappingURL=useMutation.d.ts.map
|
|
@@ -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,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,YAAY,EAAE,WAAW,EAAE,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAiF,MAAM,yBAAyB,CAAC;AAE1I,MAAM,WAAW,sBAAsB;IAAG,CAAC,GAAG,EAAE,MAAM,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE;AA4BzG,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAE5E;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAExE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAEvE;AAUD,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,CAwIzN;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAEpG;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EACpD,UAAU,EAAE,gBAAgB,CAAC,CAAC,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,EACxE,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,CAAC,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,CAAC,GAAG;IACjI,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC;QAC9B,IAAI,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,WAAW,GAAG,MAAM,CAAC;QACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAA;CACF;eAN4D,MAAM;UAAQ,OAAO,CAAC,CAAC,CAAC;YAoCtF
|
|
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,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,YAAY,EAAE,WAAW,EAAE,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAiF,MAAM,yBAAyB,CAAC;AAE1I,MAAM,WAAW,sBAAsB;IAAG,CAAC,GAAG,EAAE,MAAM,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE;AA4BzG,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAE5E;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAExE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,QAEvE;AAUD,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,CAwIzN;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAEpG;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EACpD,UAAU,EAAE,gBAAgB,CAAC,CAAC,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,EACxE,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,CAAC,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,CAAC,GAAG;IACjI,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC;QAC9B,IAAI,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,WAAW,GAAG,MAAM,CAAC;QACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAA;CACF;eAN4D,MAAM;UAAQ,OAAO,CAAC,CAAC,CAAC;YAoCtF"}
|
|
@@ -227,41 +227,3 @@ export function useListMutation(mutationFn, queryKey, options) {
|
|
|
227
227
|
mutationKey: options?.mutationKey
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
-
export function useBatchMutation(mutationFn, options) {
|
|
231
|
-
return useTanStackMutation({ mutationFn, ...options, mutationKey: options?.mutationKey });
|
|
232
|
-
}
|
|
233
|
-
export function useConditionalOptimisticMutation(mutationFn, condition, options) {
|
|
234
|
-
const queryClient = useQueryClient();
|
|
235
|
-
const { mutationKey, optimistic, onMutate, onError, onSettled, onSuccess } = options || {};
|
|
236
|
-
const mutationConfig = { mutationKey, mutationFn };
|
|
237
|
-
if (optimistic) {
|
|
238
|
-
mutationConfig.onMutate = async (variables) => {
|
|
239
|
-
const conditionMet = condition(variables);
|
|
240
|
-
if (!conditionMet || optimistic.enabled === false) {
|
|
241
|
-
const mutateCallback = onMutate;
|
|
242
|
-
const userContext = onMutate ? await mutateCallback(variables) : undefined;
|
|
243
|
-
return { userContext, conditionMet: false };
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
await queryClient.cancelQueries({ queryKey: optimistic.queryKey, exact: true });
|
|
247
|
-
// Note: Simplified conditional optimistic implementation
|
|
248
|
-
// Does not include the full consistency logic of useMutation for brevity, but could be added if needed.
|
|
249
|
-
const previousData = queryClient.getQueryData(optimistic.queryKey);
|
|
250
|
-
const mutateCallback = onMutate;
|
|
251
|
-
const userContext = onMutate ? await mutateCallback(variables) : undefined;
|
|
252
|
-
return { previousData, userContext };
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
return { userContext: undefined };
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
// ... simplified handlers ...
|
|
259
|
-
mutationConfig.onSettled = (data, error, variables, context) => {
|
|
260
|
-
if (onSettled) {
|
|
261
|
-
const settledCallback = onSettled;
|
|
262
|
-
settledCallback(data, error, variables, context?.userContext);
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
return useTanStackMutation(mutationConfig);
|
|
267
|
-
}
|
|
@@ -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;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
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;AAwCvD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAgB5E;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK;QAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;CAClD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBnG;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAe7F;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAMjC,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,QAAQ,EACtB,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,IAAI,CAuCN;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,QAAQ,EACtB,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,KAAK,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CAoDtD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { listUpdater } from "./optimisticUtils.js";
|
|
1
|
+
import { listUpdater, idsAreEqual } from "./optimisticUtils.js";
|
|
2
2
|
function ensureArray(key) {
|
|
3
3
|
return Array.isArray(key) ? key : [key];
|
|
4
4
|
}
|
|
@@ -35,16 +35,6 @@ function deepEqual(a, b) {
|
|
|
35
35
|
}
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Loose equality check for IDs (string vs number)
|
|
40
|
-
*/
|
|
41
|
-
function idsAreEqual(a, b) {
|
|
42
|
-
if (a === b)
|
|
43
|
-
return true;
|
|
44
|
-
if (a === undefined || a === null || b === undefined || b === null)
|
|
45
|
-
return false;
|
|
46
|
-
return String(a) === String(b);
|
|
47
|
-
}
|
|
48
38
|
export function startsWithKeyPrefix(key, prefix) {
|
|
49
39
|
const k = ensureArray(key);
|
|
50
40
|
const p = ensureArray(prefix);
|
|
@@ -123,16 +113,6 @@ export function syncEntityAcrossFamily(queryClient, familyPrefix, cfg, operation
|
|
|
123
113
|
const idValue = (typeof payload === "string" || typeof payload === "number") ? payload : payload?.[idField];
|
|
124
114
|
let items = picked.items;
|
|
125
115
|
if (op === "update" && idValue !== undefined) {
|
|
126
|
-
// Use custom listUpdater logic but ensure ID matching is robust if listUpdater uses strict equality
|
|
127
|
-
// Since listUpdater is imported, we should ideally modify it too or handle it here.
|
|
128
|
-
// For now, let's modify how we find the item index if we were doing it manually,
|
|
129
|
-
// but listUpdater is a black box here.
|
|
130
|
-
// Assuming listUpdater uses strict equality, we might have a problem if we pass '1' and item has 1.
|
|
131
|
-
// But listUpdater.update usually takes the whole object.
|
|
132
|
-
// To be safe, we should ensure the payload ID matches the type of the item ID in the list if possible.
|
|
133
|
-
// Or, we rely on listUpdater being robust.
|
|
134
|
-
// Let's look at listUpdater implementation later. For now, let's assume we need to fix the ID type in payload if possible.
|
|
135
|
-
// Actually, the safer way is to find the item using loose equality, get its strict ID, and use that in payload.
|
|
136
116
|
const existingItem = items.find(item => idsAreEqual(item[idField], idValue));
|
|
137
117
|
if (existingItem) {
|
|
138
118
|
const strictId = existingItem[idField];
|
|
@@ -2,6 +2,10 @@ import type { QueryKey } from "@tanstack/react-query";
|
|
|
2
2
|
import type { ListOperationConfig, OptimisticUpdateConfig } from "../types/optimistic";
|
|
3
3
|
import type { EntityWithId } from "../types/selectors";
|
|
4
4
|
import { ListOperationType } from "../types/optimistic.js";
|
|
5
|
+
/**
|
|
6
|
+
* Loose equality check for IDs (string vs number)
|
|
7
|
+
*/
|
|
8
|
+
export declare function idsAreEqual(a: unknown, b: unknown): boolean;
|
|
5
9
|
export declare const listUpdater: {
|
|
6
10
|
add: <T extends EntityWithId>(items: T[] | undefined, newItem: T) => T[];
|
|
7
11
|
update: <T extends EntityWithId>(items: T[] | undefined, updatedItem: Partial<T> & {
|
|
@@ -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":"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"}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { ListOperationType } from "../types/optimistic.js";
|
|
2
|
+
/**
|
|
3
|
+
* Loose equality check for IDs (string vs number)
|
|
4
|
+
*/
|
|
5
|
+
export function idsAreEqual(a, b) {
|
|
6
|
+
if (a === b)
|
|
7
|
+
return true;
|
|
8
|
+
if (a === undefined || a === null || b === undefined || b === null)
|
|
9
|
+
return false;
|
|
10
|
+
return String(a) === String(b);
|
|
11
|
+
}
|
|
2
12
|
export const listUpdater = {
|
|
3
13
|
add: (items, newItem) => {
|
|
4
14
|
const currentItems = items || [];
|
|
5
|
-
const existingIndex = currentItems.findIndex((item) => item.id
|
|
15
|
+
const existingIndex = currentItems.findIndex((item) => idsAreEqual(item.id, newItem.id));
|
|
6
16
|
if (existingIndex >= 0) {
|
|
7
17
|
const updatedItems = [...currentItems];
|
|
8
18
|
updatedItems[existingIndex] = newItem;
|
|
@@ -12,11 +22,11 @@ export const listUpdater = {
|
|
|
12
22
|
},
|
|
13
23
|
update: (items, updatedItem) => {
|
|
14
24
|
const currentItems = items || [];
|
|
15
|
-
return currentItems.map((item) => (item.id
|
|
25
|
+
return currentItems.map((item) => (idsAreEqual(item.id, updatedItem.id) ? { ...item, ...updatedItem } : item));
|
|
16
26
|
},
|
|
17
27
|
remove: (items, itemId) => {
|
|
18
28
|
const currentItems = items || [];
|
|
19
|
-
return currentItems.filter((item) => item.id
|
|
29
|
+
return currentItems.filter((item) => !idsAreEqual(item.id, itemId));
|
|
20
30
|
}
|
|
21
31
|
};
|
|
22
32
|
export function createAddItemConfig(queryKey, options) {
|