UNPKG

@tanstack/angular-query-experimental

Version:

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

100 lines (99 loc) 3.44 kB
import { inject, NgZone, computed, signal, effect, untracked, VERSION } from "@angular/core"; import { QueryClient, notifyManager, shouldThrowError } from "@tanstack/query-core"; import { signalProxy } from "./signal-proxy.mjs"; import { injectIsRestoring } from "./inject-is-restoring.mjs"; import { PENDING_TASKS } from "./pending-tasks-compat.mjs"; function createBaseQuery(optionsFn, Observer) { const ngZone = inject(NgZone); const pendingTasks = inject(PENDING_TASKS); const queryClient = inject(QueryClient); const isRestoring = injectIsRestoring(); const defaultedOptionsSignal = computed(() => { const defaultedOptions = queryClient.defaultQueryOptions(optionsFn()); defaultedOptions._optimisticResults = isRestoring() ? "isRestoring" : "optimistic"; return defaultedOptions; }); const observerSignal = (() => { let instance = null; return computed(() => { return instance || (instance = new Observer(queryClient, defaultedOptionsSignal())); }); })(); const optimisticResultSignal = computed( () => observerSignal().getOptimisticResult(defaultedOptionsSignal()) ); const resultFromSubscriberSignal = signal(null); effect( (onCleanup) => { const observer = observerSignal(); const defaultedOptions = defaultedOptionsSignal(); untracked(() => { observer.setOptions(defaultedOptions); }); onCleanup(() => { ngZone.run(() => resultFromSubscriberSignal.set(null)); }); }, { // Set allowSignalWrites to support Angular < v19 // Set to undefined to avoid warning on newer versions allowSignalWrites: VERSION.major < "19" || void 0 } ); effect((onCleanup) => { const observer = observerSignal(); let pendingTaskRef = null; const unsubscribe = isRestoring() ? () => void 0 : untracked( () => ngZone.runOutsideAngular(() => { return observer.subscribe( notifyManager.batchCalls((state) => { ngZone.run(() => { if (state.fetchStatus === "fetching" && !pendingTaskRef) { pendingTaskRef = pendingTasks.add(); } if (state.fetchStatus === "idle" && pendingTaskRef) { pendingTaskRef(); pendingTaskRef = null; } if (state.isError && !state.isFetching && shouldThrowError(observer.options.throwOnError, [ state.error, observer.getCurrentQuery() ])) { ngZone.onError.emit(state.error); throw state.error; } resultFromSubscriberSignal.set(state); }); }) ); }) ); onCleanup(() => { if (pendingTaskRef) { pendingTaskRef(); pendingTaskRef = null; } unsubscribe(); }); }); return signalProxy( computed(() => { const subscriberResult = resultFromSubscriberSignal(); const optimisticResult = optimisticResultSignal(); const result = subscriberResult ?? optimisticResult; const observer = observerSignal(); const originalRefetch = result.refetch; return { ...result, refetch: (...args) => { observer.setOptions(defaultedOptionsSignal()); return originalRefetch(...args); } }; }) ); } export { createBaseQuery }; //# sourceMappingURL=create-base-query.mjs.map