@tanstack/angular-query-experimental
Version:
Signals for managing, caching and syncing asynchronous and remote data in Angular
80 lines (79 loc) • 2.66 kB
JavaScript
import { assertInInjectionContext, inject, Injector, DestroyRef, NgZone, computed, signal, effect, untracked } from "@angular/core";
import { QueryClient, MutationObserver, noop, notifyManager, shouldThrowError } from "@tanstack/query-core";
import { signalProxy } from "./signal-proxy.mjs";
function injectMutation(injectMutationFn, options) {
!(options == null ? void 0 : options.injector) && assertInInjectionContext(injectMutation);
const injector = (options == null ? void 0 : options.injector) ?? inject(Injector);
const destroyRef = injector.get(DestroyRef);
const ngZone = injector.get(NgZone);
const queryClient = injector.get(QueryClient);
const optionsSignal = computed(injectMutationFn);
const observerSignal = (() => {
let instance = null;
return computed(() => {
return instance || (instance = new MutationObserver(queryClient, optionsSignal()));
});
})();
const mutateFnSignal = computed(() => {
const observer = observerSignal();
return (variables, mutateOptions) => {
observer.mutate(variables, mutateOptions).catch(noop);
};
});
const resultFromInitialOptionsSignal = computed(() => {
const observer = observerSignal();
return observer.getCurrentResult();
});
const resultFromSubscriberSignal = signal(null);
effect(
() => {
const observer = observerSignal();
const observerOptions = optionsSignal();
untracked(() => {
observer.setOptions(observerOptions);
});
},
{
injector
}
);
effect(
() => {
const observer = observerSignal();
untracked(() => {
const unsubscribe = ngZone.runOutsideAngular(
() => observer.subscribe(
notifyManager.batchCalls((state) => {
ngZone.run(() => {
if (state.isError && shouldThrowError(observer.options.throwOnError, [state.error])) {
ngZone.onError.emit(state.error);
throw state.error;
}
resultFromSubscriberSignal.set(state);
});
})
)
);
destroyRef.onDestroy(unsubscribe);
});
},
{
injector
}
);
const resultSignal = computed(() => {
const resultFromSubscriber = resultFromSubscriberSignal();
const resultFromInitialOptions = resultFromInitialOptionsSignal();
const result = resultFromSubscriber ?? resultFromInitialOptions;
return {
...result,
mutate: mutateFnSignal(),
mutateAsync: result.mutate
};
});
return signalProxy(resultSignal);
}
export {
injectMutation
};
//# sourceMappingURL=inject-mutation.mjs.map