UNPKG

@tanstack/angular-query-experimental

Version:

Signals for managing, caching and syncing asynchronous and remote data in Angular

95 lines (94 loc) 3.17 kB
import { assertInInjectionContext, inject, Injector, NgZone, computed, signal, effect, untracked } from "@angular/core"; import { QueryClient, MutationObserver, noop, notifyManager, shouldThrowError } from "@tanstack/query-core"; import { signalProxy } from "./signal-proxy.mjs"; import { PENDING_TASKS } from "./pending-tasks-compat.mjs"; function injectMutation(injectMutationFn, options) { !(options == null ? void 0 : options.injector) && assertInInjectionContext(injectMutation); const injector = (options == null ? void 0 : options.injector) ?? inject(Injector); const ngZone = injector.get(NgZone); const pendingTasks = injector.get(PENDING_TASKS); 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( (onCleanup) => { const observer = observerSignal(); let pendingTaskRef = null; untracked(() => { const unsubscribe = ngZone.runOutsideAngular( () => observer.subscribe( notifyManager.batchCalls((state) => { ngZone.run(() => { if (state.isPending && !pendingTaskRef) { pendingTaskRef = pendingTasks.add(); } if (!state.isPending && pendingTaskRef) { pendingTaskRef(); pendingTaskRef = null; } if (state.isError && shouldThrowError(observer.options.throwOnError, [state.error])) { ngZone.onError.emit(state.error); throw state.error; } resultFromSubscriberSignal.set(state); }); }) ) ); onCleanup(() => { if (pendingTaskRef) { pendingTaskRef(); pendingTaskRef = null; } 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