Website : rimsha.abasa.com
backdoor
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
canvas
/
node_modules
/
@tanstack
/
query-core
/
src
/
Filename :
queriesObserver.ts
back
Copy
import { difference, replaceAt } from './utils' import { notifyManager } from './notifyManager' import { QueryObserver } from './queryObserver' import { Subscribable } from './subscribable' import type { DefaultedQueryObserverOptions, QueryObserverOptions, QueryObserverResult, } from './types' import type { QueryClient } from './queryClient' import type { NotifyOptions } from './queryObserver' type QueriesObserverListener = (result: QueryObserverResult[]) => void export class QueriesObserver extends Subscribable<QueriesObserverListener> { private client: QueryClient private result: QueryObserverResult[] private queries: QueryObserverOptions[] private observers: QueryObserver[] private observersMap: Record<string, QueryObserver> constructor(client: QueryClient, queries?: QueryObserverOptions[]) { super() this.client = client this.queries = [] this.result = [] this.observers = [] this.observersMap = {} if (queries) { this.setQueries(queries) } } protected onSubscribe(): void { if (this.listeners.size === 1) { this.observers.forEach((observer) => { observer.subscribe((result) => { this.onUpdate(observer, result) }) }) } } protected onUnsubscribe(): void { if (!this.listeners.size) { this.destroy() } } destroy(): void { this.listeners = new Set() this.observers.forEach((observer) => { observer.destroy() }) } setQueries( queries: QueryObserverOptions[], notifyOptions?: NotifyOptions, ): void { this.queries = queries notifyManager.batch(() => { const prevObservers = this.observers const newObserverMatches = this.findMatchingObservers(this.queries) // set options for the new observers to notify of changes newObserverMatches.forEach((match) => match.observer.setOptions(match.defaultedQueryOptions, notifyOptions), ) const newObservers = newObserverMatches.map((match) => match.observer) const newObserversMap = Object.fromEntries( newObservers.map((observer) => [observer.options.queryHash, observer]), ) const newResult = newObservers.map((observer) => observer.getCurrentResult(), ) const hasIndexChange = newObservers.some( (observer, index) => observer !== prevObservers[index], ) if (prevObservers.length === newObservers.length && !hasIndexChange) { return } this.observers = newObservers this.observersMap = newObserversMap this.result = newResult if (!this.hasListeners()) { return } difference(prevObservers, newObservers).forEach((observer) => { observer.destroy() }) difference(newObservers, prevObservers).forEach((observer) => { observer.subscribe((result) => { this.onUpdate(observer, result) }) }) this.notify() }) } getCurrentResult(): QueryObserverResult[] { return this.result } getQueries() { return this.observers.map((observer) => observer.getCurrentQuery()) } getObservers() { return this.observers } getOptimisticResult(queries: QueryObserverOptions[]): QueryObserverResult[] { return this.findMatchingObservers(queries).map((match) => match.observer.getOptimisticResult(match.defaultedQueryOptions), ) } private findMatchingObservers( queries: QueryObserverOptions[], ): QueryObserverMatch[] { const prevObservers = this.observers const prevObserversMap = new Map( prevObservers.map((observer) => [observer.options.queryHash, observer]), ) const defaultedQueryOptions = queries.map((options) => this.client.defaultQueryOptions(options), ) const matchingObservers: QueryObserverMatch[] = defaultedQueryOptions.flatMap((defaultedOptions) => { const match = prevObserversMap.get(defaultedOptions.queryHash) if (match != null) { return [{ defaultedQueryOptions: defaultedOptions, observer: match }] } return [] }) const matchedQueryHashes = new Set( matchingObservers.map((match) => match.defaultedQueryOptions.queryHash), ) const unmatchedQueries = defaultedQueryOptions.filter( (defaultedOptions) => !matchedQueryHashes.has(defaultedOptions.queryHash), ) const matchingObserversSet = new Set( matchingObservers.map((match) => match.observer), ) const unmatchedObservers = prevObservers.filter( (prevObserver) => !matchingObserversSet.has(prevObserver), ) const getObserver = (options: QueryObserverOptions): QueryObserver => { const defaultedOptions = this.client.defaultQueryOptions(options) const currentObserver = this.observersMap[defaultedOptions.queryHash!] return currentObserver ?? new QueryObserver(this.client, defaultedOptions) } const newOrReusedObservers: QueryObserverMatch[] = unmatchedQueries.map( (options, index) => { if (options.keepPreviousData) { // return previous data from one of the observers that no longer match const previouslyUsedObserver = unmatchedObservers[index] if (previouslyUsedObserver !== undefined) { return { defaultedQueryOptions: options, observer: previouslyUsedObserver, } } } return { defaultedQueryOptions: options, observer: getObserver(options), } }, ) const sortMatchesByOrderOfQueries = ( a: QueryObserverMatch, b: QueryObserverMatch, ): number => defaultedQueryOptions.indexOf(a.defaultedQueryOptions) - defaultedQueryOptions.indexOf(b.defaultedQueryOptions) return matchingObservers .concat(newOrReusedObservers) .sort(sortMatchesByOrderOfQueries) } private onUpdate(observer: QueryObserver, result: QueryObserverResult): void { const index = this.observers.indexOf(observer) if (index !== -1) { this.result = replaceAt(this.result, index, result) this.notify() } } private notify(): void { notifyManager.batch(() => { this.listeners.forEach(({ listener }) => { listener(this.result) }) }) } } type QueryObserverMatch = { defaultedQueryOptions: DefaultedQueryObserverOptions observer: QueryObserver }