Skip to content

Commit e4561e7

Browse files
committed
chore: add deprecation for fields 'resetOnDispose' (renamed to 'resetOnDestroy'), will be removed in next major; refactor: optimize constructors of mobx queries and mobx mutation
1 parent 4f2502c commit e4561e7

File tree

7 files changed

+543
-164
lines changed

7 files changed

+543
-164
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
{ ignore: Object.keys(packageJson.peerDependencies) },
99
],
1010
'unicorn/prevent-abbreviations': 'off',
11-
'sonarjs/no-redundant-optional': 'off'
11+
'sonarjs/no-redundant-optional': 'off',
12+
'sonarjs/deprecation': 'off'
1213
},
1314
};

src/mobx-inifinite-query.ts

Lines changed: 88 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -61,34 +61,37 @@ export class MobxInfiniteQuery<
6161
TQueryKey,
6262
TPageParam
6363
>['enabled'];
64-
65-
constructor({
66-
queryClient,
67-
onInit,
68-
options: getDynamicOptions,
69-
onDone,
70-
onError,
71-
// eslint-disable-next-line sonarjs/deprecation
72-
disposer,
73-
abortSignal: outerAbortSignal,
74-
resetOnDispose,
75-
enableOnDemand,
76-
queryKey: queryKeyOrDynamicQueryKey,
77-
...options
78-
}: MobxInfiniteQueryConfig<TData, TError, TQueryKey, TPageParam>) {
79-
this.abortController = new LinkedAbortController(outerAbortSignal);
64+
private _observerSubscription?: VoidFunction;
65+
66+
constructor(
67+
protected config: MobxInfiniteQueryConfig<
68+
TData,
69+
TError,
70+
TQueryKey,
71+
TPageParam
72+
>,
73+
) {
74+
const {
75+
queryClient,
76+
queryKey: queryKeyOrDynamicQueryKey,
77+
...restOptions
78+
} = config;
79+
this.abortController = new LinkedAbortController(config.abortSignal);
8080
this.queryClient = queryClient;
8181
this._result = undefined as any;
8282
this.isResultRequsted = false;
83-
this.isEnabledOnResultDemand = enableOnDemand ?? false;
83+
this.isEnabledOnResultDemand = config.enableOnDemand ?? false;
8484

85-
if (queryClient instanceof MobxQueryClient && enableOnDemand == null) {
85+
if (
86+
queryClient instanceof MobxQueryClient &&
87+
config.enableOnDemand == null
88+
) {
8689
this.isEnabledOnResultDemand =
8790
queryClient.queryFeatures.enableOnDemand ?? false;
8891
}
8992

90-
if (disposer) {
91-
disposer.add(() => this.dispose());
93+
if (config.disposer) {
94+
config.disposer.add(() => this.dispose());
9295
}
9396

9497
observable.deep(this, '_result');
@@ -99,50 +102,46 @@ export class MobxInfiniteQuery<
99102

100103
makeObservable(this);
101104

102-
const mergedOptions = {
103-
...options,
104-
...getDynamicOptions?.(this),
105-
};
106-
107-
if (queryKeyOrDynamicQueryKey) {
108-
if (typeof queryKeyOrDynamicQueryKey === 'function') {
109-
mergedOptions.queryKey = queryKeyOrDynamicQueryKey();
110-
111-
reaction(
112-
() => queryKeyOrDynamicQueryKey(),
113-
(queryKey) => {
114-
this.update({
115-
queryKey,
116-
});
117-
},
118-
{
119-
signal: this.abortController.signal,
120-
},
121-
);
122-
} else {
123-
mergedOptions.queryKey = queryKeyOrDynamicQueryKey;
124-
}
125-
}
126-
127105
this.options = this.createOptions({
128-
...mergedOptions,
129-
queryKey: (mergedOptions.queryKey ?? []) as TQueryKey,
106+
...restOptions,
107+
...config.options?.(this),
130108
});
131109

110+
if (typeof queryKeyOrDynamicQueryKey === 'function') {
111+
this.options.queryKey = queryKeyOrDynamicQueryKey();
112+
113+
reaction(
114+
() => queryKeyOrDynamicQueryKey(),
115+
(queryKey) => {
116+
this.update({
117+
queryKey,
118+
});
119+
},
120+
{
121+
signal: this.abortController.signal,
122+
},
123+
);
124+
} else {
125+
this.options.queryKey =
126+
queryKeyOrDynamicQueryKey ?? this.options.queryKey ?? [];
127+
}
128+
132129
// Tracking props visit should be done in MobX, by default.
133130
this.options.notifyOnChangeProps =
134-
options.notifyOnChangeProps ??
131+
restOptions.notifyOnChangeProps ??
135132
queryClient.getDefaultOptions().queries?.notifyOnChangeProps ??
136133
'all';
137134

138135
this.queryObserver = new InfiniteQueryObserver(queryClient, this.options);
139136

140137
this.updateResult(this.queryObserver.getOptimisticResult(this.options));
141138

142-
const subscription = this.queryObserver.subscribe(this.updateResult);
139+
this._observerSubscription = this.queryObserver.subscribe(
140+
this.updateResult,
141+
);
143142

144-
if (getDynamicOptions) {
145-
reaction(() => getDynamicOptions(this), this.update, {
143+
if (config.options) {
144+
reaction(() => config.options!(this), this.update, {
146145
signal: this.abortController.signal,
147146
});
148147
}
@@ -152,7 +151,7 @@ export class MobxInfiniteQuery<
152151
() => this.isResultRequsted,
153152
(isRequested) => {
154153
if (isRequested) {
155-
this.update(getDynamicOptions ? getDynamicOptions(this) : {});
154+
this.update(config.options ? config.options(this) : {});
156155
}
157156
},
158157
{
@@ -161,30 +160,16 @@ export class MobxInfiniteQuery<
161160
);
162161
}
163162

164-
if (onDone) {
165-
this.onDone(onDone);
163+
if (config.onDone) {
164+
this.onDone(config.onDone);
166165
}
167-
if (onError) {
168-
this.onError(onError);
166+
if (config.onError) {
167+
this.onError(config.onError);
169168
}
170169

171-
this.abortController.signal.addEventListener('abort', () => {
172-
subscription();
173-
174-
this.queryObserver.getCurrentQuery().destroy();
175-
this.queryObserver.destroy();
176-
this.isResultRequsted = false;
170+
this.abortController.signal.addEventListener('abort', this.handleAbort);
177171

178-
if (
179-
resetOnDispose ||
180-
(queryClient instanceof MobxQueryClient &&
181-
queryClient.queryFeatures.resetOnDispose)
182-
) {
183-
this.reset();
184-
}
185-
});
186-
187-
onInit?.(this);
172+
this.config.onInit?.(this);
188173
}
189174

190175
protected createQueryHash(
@@ -330,7 +315,37 @@ export class MobxInfiniteQuery<
330315
);
331316
}
332317

333-
dispose() {
318+
protected handleAbort = () => {
319+
this._observerSubscription?.();
320+
321+
this.queryObserver.getCurrentQuery().destroy();
322+
this.queryObserver.destroy();
323+
this.isResultRequsted = false;
324+
325+
let isNeedToReset =
326+
this.config.resetOnDestroy || this.config.resetOnDispose;
327+
328+
if (this.queryClient instanceof MobxQueryClient && !isNeedToReset) {
329+
isNeedToReset =
330+
this.queryClient.queryFeatures.resetOnDestroy ||
331+
this.queryClient.queryFeatures.resetOnDispose;
332+
}
333+
334+
if (isNeedToReset) {
335+
this.reset();
336+
}
337+
338+
delete this._observerSubscription;
339+
};
340+
341+
destroy() {
334342
this.abortController.abort();
335343
}
344+
345+
/**
346+
* @deprecated use `destroy`
347+
*/
348+
dispose() {
349+
this.destroy();
350+
}
336351
}

src/mobx-mutation.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,26 @@ export class MobxMutation<
2626

2727
result: MutationObserverResult<TData, TError, TVariables, TContext>;
2828

29-
constructor({
30-
queryClient,
31-
onInit,
32-
// eslint-disable-next-line sonarjs/deprecation
33-
disposer,
34-
abortSignal: outerAbortSignal,
35-
resetOnDispose,
36-
...options
37-
}: MobxMutationConfig<TData, TVariables, TError, TContext>) {
38-
this.abortController = new LinkedAbortController(outerAbortSignal);
29+
private _observerSubscription?: VoidFunction;
30+
31+
constructor(
32+
protected config: MobxMutationConfig<TData, TVariables, TError, TContext>,
33+
) {
34+
const { queryClient, ...restOptions } = config;
35+
this.abortController = new LinkedAbortController(config.abortSignal);
3936
this.queryClient = queryClient;
4037
this.result = undefined as any;
4138

42-
if (this.queryClient && disposer) {
43-
disposer.add(() => this.dispose());
39+
if (config.disposer) {
40+
config.disposer.add(() => this.dispose());
4441
}
4542

4643
observable.deep(this, 'result');
4744
action.bound(this, 'updateResult');
4845

4946
makeObservable(this);
5047

51-
this.mutationOptions = this.queryClient.defaultMutationOptions(options);
48+
this.mutationOptions = this.queryClient.defaultMutationOptions(restOptions);
5249

5350
this.mutationObserver = new MutationObserver<
5451
TData,
@@ -59,21 +56,23 @@ export class MobxMutation<
5956

6057
this.updateResult(this.mutationObserver.getCurrentResult());
6158

62-
const subscription = this.mutationObserver.subscribe(this.updateResult);
59+
this._observerSubscription = this.mutationObserver.subscribe(
60+
this.updateResult,
61+
);
6362

6463
this.abortController.signal.addEventListener('abort', () => {
65-
subscription();
64+
this._observerSubscription?.();
6665

6766
if (
68-
resetOnDispose ||
67+
config.resetOnDispose ||
6968
(queryClient instanceof MobxQueryClient &&
7069
queryClient.mutationFeatures.resetOnDispose)
7170
) {
7271
this.reset();
7372
}
7473
});
7574

76-
onInit?.(this);
75+
config.onInit?.(this);
7776
}
7877

7978
async mutate(
@@ -125,6 +124,25 @@ export class MobxMutation<
125124
this.mutationObserver.reset();
126125
}
127126

127+
protected handleAbort = () => {
128+
this._observerSubscription?.();
129+
130+
let isNeedToReset =
131+
this.config.resetOnDestroy || this.config.resetOnDispose;
132+
133+
if (this.queryClient instanceof MobxQueryClient && !isNeedToReset) {
134+
isNeedToReset =
135+
this.queryClient.mutationFeatures.resetOnDestroy ||
136+
this.queryClient.mutationFeatures.resetOnDispose;
137+
}
138+
139+
if (isNeedToReset) {
140+
this.reset();
141+
}
142+
143+
delete this._observerSubscription;
144+
};
145+
128146
dispose() {
129147
this.abortController.abort();
130148
}

src/mobx-mutation.types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ import { MobxQueryClient } from './mobx-query-client';
1111
export interface MobxMutationFeatures {
1212
/**
1313
* Reset mutation when dispose is called
14+
*
15+
* @deprecated Please use 'resetOnDestroy'
1416
*/
1517
resetOnDispose?: boolean;
18+
19+
/**
20+
* Reset mutation when destroy or abort signal is called
21+
*/
22+
resetOnDestroy?: boolean;
1623
}
1724

1825
export interface MobxMutationConfig<

0 commit comments

Comments
 (0)