@qiaopeng/tanstack-query-plus 0.2.5 → 0.2.7
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/dist/hooks/useMutation.d.ts +7 -1
- package/dist/hooks/useMutation.d.ts.map +1 -1
- package/dist/hooks/useMutation.js +36 -2
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/consistency.d.ts +20 -9
- package/dist/utils/consistency.d.ts.map +1 -1
- package/dist/utils/consistency.js +105 -52
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/optimisticUtils.d.ts +7 -0
- package/dist/utils/optimisticUtils.d.ts.map +1 -1
- package/dist/utils/optimisticUtils.js +21 -0
- package/package.json +1 -1
|
@@ -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;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,YAAY,EAAE,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../../src/hooks/useMutation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useQueryClient, useMutation as useTanStackMutation } from "@tanstack/react-query";
|
|
2
2
|
import { DEFAULT_MUTATION_CONFIG } from "../core/config.js";
|
|
3
|
+
import { syncEntityAcrossFamily, syncEntityAcrossFamilyOptimistic, DEFAULT_FAMILY_SYNC } from "../utils/consistency.js";
|
|
3
4
|
function deriveFamilyKey(queryKey) {
|
|
4
5
|
const arr = Array.isArray(queryKey) ? [...queryKey] : [queryKey];
|
|
5
6
|
while (arr.length > 1) {
|
|
@@ -22,7 +23,7 @@ function isListFamilyKey(queryKey) {
|
|
|
22
23
|
}
|
|
23
24
|
export function useMutation(options) {
|
|
24
25
|
const queryClient = useQueryClient();
|
|
25
|
-
const { optimistic, onMutate, onError, onSuccess, onSettled, ...restOptions } = options;
|
|
26
|
+
const { optimistic, onMutate, onError, onSuccess, onSettled, consistency, ...restOptions } = options;
|
|
26
27
|
const mutationConfig = {
|
|
27
28
|
...restOptions,
|
|
28
29
|
retry: restOptions.retry ?? DEFAULT_MUTATION_CONFIG?.retry,
|
|
@@ -65,9 +66,18 @@ export function useMutation(options) {
|
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
queryClient.setQueryData(optimistic.queryKey, (oldData) => optimistic.updater(oldData, mappedVariables));
|
|
69
|
+
let familyRollbackData = [];
|
|
70
|
+
const shouldSync = (consistency?.mode ?? "sync+invalidate") === "sync+invalidate";
|
|
71
|
+
if (shouldSync && optimistic?.queryKey) {
|
|
72
|
+
const familyKey = optimistic.familyKey ?? deriveFamilyKey(optimistic.queryKey);
|
|
73
|
+
const payload = typeof variables === "object" && variables !== null ? (variables.data ?? variables) : variables;
|
|
74
|
+
const op = typeof variables?.operation === "string" ? variables.operation : "update";
|
|
75
|
+
const cfg = consistency?.familySync ?? DEFAULT_FAMILY_SYNC;
|
|
76
|
+
familyRollbackData = syncEntityAcrossFamilyOptimistic(queryClient, familyKey, cfg, op, payload);
|
|
77
|
+
}
|
|
68
78
|
const mutateCallback = onMutate;
|
|
69
79
|
const userContext = onMutate ? await mutateCallback(variables) : undefined;
|
|
70
|
-
return { previousData, userContext };
|
|
80
|
+
return { previousData, userContext, familyRollbackData };
|
|
71
81
|
}
|
|
72
82
|
catch (error) {
|
|
73
83
|
return { userContext: undefined };
|
|
@@ -77,6 +87,11 @@ export function useMutation(options) {
|
|
|
77
87
|
if (context?.previousData !== undefined) {
|
|
78
88
|
queryClient.setQueryData(optimistic.queryKey, context.previousData);
|
|
79
89
|
}
|
|
90
|
+
if (context?.familyRollbackData) {
|
|
91
|
+
context.familyRollbackData.forEach(item => {
|
|
92
|
+
queryClient.setQueryData(item.queryKey, item.previousData);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
80
95
|
if (optimistic.rollback && context?.previousData !== undefined) {
|
|
81
96
|
try {
|
|
82
97
|
optimistic.rollback(context.previousData, error);
|
|
@@ -89,6 +104,14 @@ export function useMutation(options) {
|
|
|
89
104
|
}
|
|
90
105
|
};
|
|
91
106
|
mutationConfig.onSuccess = (data, variables, context) => {
|
|
107
|
+
const shouldSync = (consistency?.mode ?? "sync+invalidate") === "sync+invalidate";
|
|
108
|
+
if (shouldSync && optimistic?.queryKey) {
|
|
109
|
+
const familyKey = optimistic.familyKey ?? deriveFamilyKey(optimistic.queryKey);
|
|
110
|
+
const payload = typeof variables === "object" && variables !== null ? (variables.data ?? variables) : variables;
|
|
111
|
+
const op = typeof variables?.operation === "string" ? variables.operation : "update";
|
|
112
|
+
const cfg = consistency?.familySync ?? DEFAULT_FAMILY_SYNC;
|
|
113
|
+
syncEntityAcrossFamily(queryClient, familyKey, cfg, op, payload);
|
|
114
|
+
}
|
|
92
115
|
const scope = optimistic.invalidateScope ?? (isListFamilyKey(optimistic.queryKey) ? "family" : "exact");
|
|
93
116
|
const invalidations = [];
|
|
94
117
|
if (scope !== "none") {
|
|
@@ -103,6 +126,9 @@ export function useMutation(options) {
|
|
|
103
126
|
if (Array.isArray(optimistic.relatedKeys) && optimistic.relatedKeys.length > 0) {
|
|
104
127
|
optimistic.relatedKeys.forEach((k) => invalidations.push({ queryKey: k }));
|
|
105
128
|
}
|
|
129
|
+
if (Array.isArray(optimistic.invalidates) && optimistic.invalidates.length > 0) {
|
|
130
|
+
optimistic.invalidates.forEach((k) => invalidations.push({ queryKey: k }));
|
|
131
|
+
}
|
|
106
132
|
if (invalidations.length > 0) {
|
|
107
133
|
const seen = new Set();
|
|
108
134
|
const tasks = invalidations
|
|
@@ -142,6 +168,14 @@ export function useListMutation(mutationFn, queryKey, options) {
|
|
|
142
168
|
const queryClient = useQueryClient();
|
|
143
169
|
return useTanStackMutation({
|
|
144
170
|
mutationFn,
|
|
171
|
+
onSuccess: (_data, variables) => {
|
|
172
|
+
const mode = options?.consistency?.mode ?? "sync+invalidate";
|
|
173
|
+
if (mode === "sync+invalidate") {
|
|
174
|
+
const familyKey = deriveFamilyKey(queryKey);
|
|
175
|
+
const cfg = options?.consistency?.familySync ?? DEFAULT_FAMILY_SYNC;
|
|
176
|
+
syncEntityAcrossFamily(queryClient, familyKey, cfg, variables.operation, variables.data);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
145
179
|
onSettled: () => {
|
|
146
180
|
const familyKey = deriveFamilyKey(queryKey);
|
|
147
181
|
queryClient.invalidateQueries({ queryKey: familyKey, exact: false });
|
package/dist/types/index.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export interface MutationContext<TData = unknown, TContext = unknown> {
|
|
|
10
10
|
previousData?: TData;
|
|
11
11
|
userContext?: TContext;
|
|
12
12
|
conditionMet?: boolean;
|
|
13
|
+
familyRollbackData?: Array<{
|
|
14
|
+
queryKey: QueryKey;
|
|
15
|
+
previousData: unknown;
|
|
16
|
+
}>;
|
|
13
17
|
}
|
|
14
18
|
export interface MutationOptions<TData, TError, TVariables, TContext = unknown> extends UseMutationOptions<TData, TError, TVariables, TContext> {
|
|
15
19
|
optimistic?: {
|
|
@@ -21,6 +25,20 @@ export interface MutationOptions<TData, TError, TVariables, TContext = unknown>
|
|
|
21
25
|
invalidateScope?: "none" | "exact" | "family";
|
|
22
26
|
familyKey?: QueryKey;
|
|
23
27
|
relatedKeys?: QueryKey[];
|
|
28
|
+
invalidates?: QueryKey[];
|
|
29
|
+
};
|
|
30
|
+
consistency?: {
|
|
31
|
+
familySync?: {
|
|
32
|
+
idField?: string;
|
|
33
|
+
listSelector?: (data: unknown) => {
|
|
34
|
+
items: unknown[];
|
|
35
|
+
total?: number;
|
|
36
|
+
} | null;
|
|
37
|
+
writeBack?: (old: unknown, items: unknown[], total?: number) => unknown;
|
|
38
|
+
maxKeys?: number;
|
|
39
|
+
enableForOperations?: Array<"update" | "delete">;
|
|
40
|
+
};
|
|
41
|
+
mode?: "sync+invalidate" | "invalidate-only";
|
|
24
42
|
};
|
|
25
43
|
}
|
|
26
44
|
//# 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,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;
|
|
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,CAAC;IAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAAE;AAC1N,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;QACzB,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"}
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import type { QueryClient, QueryKey } from "@tanstack/react-query";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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) =>
|
|
10
|
-
items:
|
|
6
|
+
listSelector?: (data: unknown) => {
|
|
7
|
+
items: EntityWithId[];
|
|
11
8
|
total?: number;
|
|
12
9
|
} | null;
|
|
13
|
-
|
|
10
|
+
writeBack?: (old: unknown, items: EntityWithId[], total?: number) => unknown;
|
|
11
|
+
maxKeys?: number;
|
|
12
|
+
enableForOperations?: Array<"update" | "delete">;
|
|
13
|
+
};
|
|
14
|
+
export declare function defaultListSelector(data: unknown): {
|
|
15
|
+
items: EntityWithId[];
|
|
16
|
+
total?: number;
|
|
17
|
+
} | null;
|
|
18
|
+
export declare function defaultWriteBack(old: unknown, items: EntityWithId[], total?: number): unknown;
|
|
19
|
+
export declare const DEFAULT_FAMILY_SYNC: FamilySyncConfig;
|
|
20
|
+
export declare function syncEntityAcrossFamily(queryClient: QueryClient, familyPrefix: QueryKey, cfg: FamilySyncConfig, operation: string, payload: Partial<EntityWithId>): void;
|
|
21
|
+
export declare function syncEntityAcrossFamilyOptimistic(queryClient: QueryClient, familyPrefix: QueryKey, cfg: FamilySyncConfig, operation: string, payload: Partial<EntityWithId>): Array<{
|
|
22
|
+
queryKey: QueryKey;
|
|
23
|
+
previousData: unknown;
|
|
24
|
+
}>;
|
|
14
25
|
//# 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;
|
|
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;AAC1R,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASnG;AACD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAe7F;AACD,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;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,CA6CtD"}
|
|
@@ -1,68 +1,121 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
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)))
|
|
9
17
|
return false;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
} return true; }
|
|
19
|
+
export 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 };
|
|
13
30
|
}
|
|
14
|
-
return
|
|
31
|
+
return null;
|
|
15
32
|
}
|
|
16
|
-
export function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
export 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;
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(obj.items)) {
|
|
43
|
+
obj.items = items;
|
|
44
|
+
if (typeof total !== "undefined")
|
|
45
|
+
obj.total = total;
|
|
46
|
+
return obj;
|
|
47
|
+
}
|
|
22
48
|
}
|
|
23
|
-
return
|
|
49
|
+
return { items, total };
|
|
24
50
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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))
|
|
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 });
|
|
34
71
|
}
|
|
35
|
-
|
|
72
|
+
else if (op === "delete" && idValue !== undefined) {
|
|
73
|
+
items = listUpdater.remove(items, idValue);
|
|
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);
|
|
36
78
|
});
|
|
37
79
|
}
|
|
38
|
-
export function
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
export function syncEntityAcrossFamilyOptimistic(queryClient, familyPrefix, cfg, operation, payload) {
|
|
81
|
+
const rollbackData = [];
|
|
82
|
+
const enabledOps = cfg.enableForOperations ?? ["update", "delete"];
|
|
83
|
+
const op = String(operation).toLowerCase();
|
|
84
|
+
if (!enabledOps.includes(op))
|
|
85
|
+
return rollbackData;
|
|
86
|
+
const idField = cfg.idField ?? "id";
|
|
87
|
+
const cache = queryClient.getQueryCache();
|
|
88
|
+
const queries = cache.findAll({ predicate: (q) => startsWithKeyPrefix(q.queryKey, familyPrefix) });
|
|
89
|
+
const limited = typeof cfg.maxKeys === "number" && cfg.maxKeys > 0 ? queries.slice(0, cfg.maxKeys) : queries;
|
|
90
|
+
limited.forEach((q) => {
|
|
91
|
+
const key = q.queryKey;
|
|
92
|
+
const old = queryClient.getQueryData(key);
|
|
93
|
+
const picked = (cfg.listSelector ?? defaultListSelector)(old);
|
|
94
|
+
if (!picked || !Array.isArray(picked.items))
|
|
45
95
|
return;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const nextItems = updateArrayById(selected.items, updatedEntity, idField);
|
|
55
|
-
const next = { ...oldData, items: nextItems };
|
|
56
|
-
queryClient.setQueryData(key, next);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
96
|
+
const idValue = payload?.[idField];
|
|
97
|
+
let items = picked.items;
|
|
98
|
+
let shouldUpdate = false;
|
|
99
|
+
if (op === "update" && idValue !== undefined) {
|
|
100
|
+
const exists = items.some(item => item[idField] === idValue);
|
|
101
|
+
if (exists) {
|
|
102
|
+
items = listUpdater.update(items, { ...payload, id: idValue });
|
|
103
|
+
shouldUpdate = true;
|
|
59
104
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
105
|
+
}
|
|
106
|
+
else if (op === "delete" && idValue !== undefined) {
|
|
107
|
+
const exists = items.some(item => item[idField] === idValue);
|
|
108
|
+
if (exists) {
|
|
109
|
+
items = listUpdater.remove(items, idValue);
|
|
110
|
+
shouldUpdate = true;
|
|
65
111
|
}
|
|
66
112
|
}
|
|
113
|
+
if (shouldUpdate) {
|
|
114
|
+
rollbackData.push({ queryKey: key, previousData: old });
|
|
115
|
+
const total = typeof picked.total === "number" && op === "delete" ? Math.max(0, picked.total - 1) : picked.total;
|
|
116
|
+
const next = (cfg.writeBack ?? defaultWriteBack)(old, items, total);
|
|
117
|
+
queryClient.setQueryData(key, next);
|
|
118
|
+
}
|
|
67
119
|
});
|
|
120
|
+
return rollbackData;
|
|
68
121
|
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -6,4 +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 { startsWithKeyPrefix, syncEntityAcrossFamily, DEFAULT_FAMILY_SYNC, type FamilySyncConfig } from "./consistency.js";
|
|
9
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"}
|
|
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"}
|
package/dist/utils/index.js
CHANGED
|
@@ -6,3 +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 { 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":"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"}
|
|
@@ -83,3 +83,24 @@ export function conditionalUpdateItems(items, predicate, updater) {
|
|
|
83
83
|
return { ...item, ...updater(item) };
|
|
84
84
|
} return item; });
|
|
85
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
|
+
}
|