From 2788165166c148bf7c400832ad28ca112ba94248 Mon Sep 17 00:00:00 2001 From: zam Date: Thu, 22 Feb 2024 10:07:37 +0200 Subject: [PATCH] fixed bug: cannot mutate while not being observed --- package.json | 2 +- src/Mutation.ts | 229 ++++++++++++++++++++++++++++-------------------- 2 files changed, 136 insertions(+), 95 deletions(-) diff --git a/package.json b/package.json index eca5004..5c88951 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/Mutation.ts b/src/Mutation.ts index 6989516..520baeb 100644 --- a/src/Mutation.ts +++ b/src/Mutation.ts @@ -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; - constructor(queryClient: QueryClient, mutationOptions: () => MutationObserverOptions) { - 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; + 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 | undefined, + ) { + if (!this.isObserved) { + this.mutation.setupDispoables(); + this.mutation.mutate(variables, options); + this.mutation.dispose(); + return; } - mutate(variables: TVariables, options?: MutateOptions | undefined ) { - this.mutation.mutate(variables, options); - } - updateOptions(options: () => MutationObserverOptions) { - this.mutation.updateOptions(options); - } + this.mutation.mutate(variables, options); + } + updateOptions( + options: () => MutationObserverOptions, + ) { + this.mutation.updateOptions(options); } - class _MobxMutation< +} +class _MobxMutation< TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown, > { - queryClient: QueryClient; - _queryOptions: () => MutationObserverOptions; - mObserver!: MutationObserver; - public state!:MutationObserverResult; - private dispoables: (() => void)[] = []; - constructor(queryClient: QueryClient, mutationOptions: () => MutationObserverOptions) { - 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 | undefined ) { - this.mObserver.mutate(variables, options) - } - update(state: MutationObserverResult) { - this.state = state; - } - updateOptions(options: () => MutationObserverOptions) { - 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; + public state!: MutationObserverResult; + 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 | undefined, + ) { + this.mObserver.mutate(variables, options); + } + update(state: MutationObserverResult) { + this.state = state; + } + updateOptions( + options: () => MutationObserverOptions, + ) { + this._queryOptions = options; + } + _updateOptions() { + this.mObserver.setOptions(this.mutationOptions); + } + + dispose() { + this.dispoables.forEach((fn) => fn()); } - - export { MobxMutation }; - \ No newline at end of file +} + +export { MobxMutation };