Skip to content

Commit

Permalink
fixed bug: cannot mutate while not being observed
Browse files Browse the repository at this point in the history
  • Loading branch information
sandstone991 committed Feb 22, 2024
1 parent 6551a6b commit 2788165
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 95 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "mobbing-query",
"description": "A very tiny wrapper around tanstack/query-core to provide observable queries inside mobx",
"author": "Ahmed Azzam",
"version": "1.0.1",
"version": "1.0.2",
"repository": {
"type": "git",
"url": "https://github.com/sandstone991/MobQ"
Expand Down
229 changes: 135 additions & 94 deletions src/Mutation.ts
Original file line number Diff line number Diff line change
@@ -1,108 +1,149 @@
import {
action,
makeObservable,
observable,
reaction,
onBecomeUnobserved,
onBecomeObserved,
computed,
} from "mobx";
import {
QueryClient,
MutationObserver,
MutationObserverResult,
DefaultError,
MutationObserverOptions,
MutateOptions,
} from "@tanstack/query-core";
class MobxMutation<
action,
makeObservable,
observable,
reaction,
onBecomeUnobserved,
onBecomeObserved,
computed,
} from 'mobx';
import {
QueryClient,
MutationObserver,
MutationObserverResult,
DefaultError,
MutationObserverOptions,
MutateOptions,
} from '@tanstack/query-core';
class MobxMutation<
TData = unknown,
TError = DefaultError,
TVariables = void,
TContext = unknown,
> {
private mutation: _MobxMutation<TData, TError, TVariables, TContext>;
constructor(queryClient: QueryClient, mutationOptions: () => MutationObserverOptions<TData, TError, TVariables, TContext>) {
this.mutation = new _MobxMutation(queryClient, mutationOptions);
makeObservable(this, {
// @ts-expect-error Mobx can see it don't worry
mutation: observable.ref,
});
onBecomeObserved(this, "mutation", () => {
this.mutation.setupDispoables();
});
onBecomeUnobserved(this, "mutation", () => {
this.mutation.dispose();
});
this.mutation;
}
get state() {
return this.mutation.state;
private mutation: _MobxMutation<TData, TError, TVariables, TContext>;
private isObserved = false;
constructor(
queryClient: QueryClient,
mutationOptions: () => MutationObserverOptions<
TData,
TError,
TVariables,
TContext
>,
) {
this.mutation = new _MobxMutation(queryClient, mutationOptions);
makeObservable(this, {
// @ts-expect-error Mobx can see it don't worry
mutation: observable.ref,
});
onBecomeObserved(this, 'mutation', () => {
this.isObserved = true;
this.mutation.setupDispoables();
});
onBecomeUnobserved(this, 'mutation', () => {
this.isObserved = false;
this.mutation.dispose();
});
this.mutation;
}
get state() {
return this.mutation.state;
}
mutate(
variables: TVariables,
options?: MutateOptions<TData, TError, TVariables, TContext> | undefined,
) {
if (!this.isObserved) {
this.mutation.setupDispoables();
this.mutation.mutate(variables, options);
this.mutation.dispose();
return;
}
mutate(variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext> | undefined ) {
this.mutation.mutate(variables, options);
}
updateOptions(options: () => MutationObserverOptions<TData, TError, TVariables, TContext>) {
this.mutation.updateOptions(options);
}
this.mutation.mutate(variables, options);
}
updateOptions(
options: () => MutationObserverOptions<TData, TError, TVariables, TContext>,
) {
this.mutation.updateOptions(options);
}
class _MobxMutation<
}
class _MobxMutation<
TData = unknown,
TError = DefaultError,
TVariables = void,
TContext = unknown,
> {
queryClient: QueryClient;
_queryOptions: () => MutationObserverOptions<TData, TError, TVariables, TContext>;
mObserver!: MutationObserver<TData, TError, TVariables, TContext>;
public state!:MutationObserverResult<TData, TError, TVariables, TContext>;
private dispoables: (() => void)[] = [];
constructor(queryClient: QueryClient, mutationOptions: () => MutationObserverOptions<TData, TError, TVariables, TContext>) {
makeObservable(this, {
state: observable.ref,
update: action,
mutationOptions: computed,
mutate: action,
_updateOptions: action.bound,
});
this.queryClient = queryClient;
this._queryOptions = mutationOptions;
}
get mutationOptions() {
return this._queryOptions();
}
setupDispoables() {
this.mObserver = new MutationObserver(this.queryClient, this.mutationOptions);
this.dispoables.push(
...[
this.mObserver.subscribe((e) => {
this.update(e);
}),
reaction(() => this.mutationOptions, this._updateOptions),
() => {
this.mObserver.reset();

},
],
);
}
mutate(variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext> | undefined ) {
this.mObserver.mutate(variables, options)
}
update(state: MutationObserverResult<TData, TError, TVariables, TContext>) {
this.state = state;
}
updateOptions(options: () => MutationObserverOptions<TData, TError, TVariables, TContext>) {
this._queryOptions = options;
}
_updateOptions() {
this.mObserver.setOptions(this.mutationOptions);
}

dispose() {
this.dispoables.forEach((fn) => fn());
}
queryClient: QueryClient;
_queryOptions: () => MutationObserverOptions<
TData,
TError,
TVariables,
TContext
>;
mObserver!: MutationObserver<TData, TError, TVariables, TContext>;
public state!: MutationObserverResult<TData, TError, TVariables, TContext>;
private dispoables: (() => void)[] = [];
constructor(
queryClient: QueryClient,
mutationOptions: () => MutationObserverOptions<
TData,
TError,
TVariables,
TContext
>,
) {
makeObservable(this, {
state: observable.ref,
update: action,
mutationOptions: computed,
mutate: action,
_updateOptions: action.bound,
});
this.queryClient = queryClient;
this._queryOptions = mutationOptions;
}
get mutationOptions() {
return this._queryOptions();
}
setupDispoables() {
this.mObserver = new MutationObserver(
this.queryClient,
this.mutationOptions,
);
this.dispoables.push(
...[
this.mObserver.subscribe((e) => {
this.update(e);
}),
reaction(() => this.mutationOptions, this._updateOptions),
() => {
this.mObserver.reset();
},
],
);
}
mutate(
variables: TVariables,
options?: MutateOptions<TData, TError, TVariables, TContext> | undefined,
) {
this.mObserver.mutate(variables, options);
}
update(state: MutationObserverResult<TData, TError, TVariables, TContext>) {
this.state = state;
}
updateOptions(
options: () => MutationObserverOptions<TData, TError, TVariables, TContext>,
) {
this._queryOptions = options;
}
_updateOptions() {
this.mObserver.setOptions(this.mutationOptions);
}

dispose() {
this.dispoables.forEach((fn) => fn());
}
export { MobxMutation };
}

export { MobxMutation };

0 comments on commit 2788165

Please sign in to comment.