123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- 'use strict';
- Object.defineProperty(exports, '__esModule', { value: true });
- var utils = require('./utils.js');
- var notifyManager = require('./notifyManager.js');
- var queryObserver = require('./queryObserver.js');
- var subscribable = require('./subscribable.js');
- class QueriesObserver extends subscribable.Subscribable {
- constructor(client, queries) {
- super();
- this.client = client;
- this.queries = [];
- this.result = [];
- this.observers = [];
- this.observersMap = {};
- if (queries) {
- this.setQueries(queries);
- }
- }
- onSubscribe() {
- if (this.listeners.size === 1) {
- this.observers.forEach(observer => {
- observer.subscribe(result => {
- this.onUpdate(observer, result);
- });
- });
- }
- }
- onUnsubscribe() {
- if (!this.listeners.size) {
- this.destroy();
- }
- }
- destroy() {
- this.listeners = new Set();
- this.observers.forEach(observer => {
- observer.destroy();
- });
- }
- setQueries(queries, notifyOptions) {
- this.queries = queries;
- notifyManager.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;
- }
- utils.difference(prevObservers, newObservers).forEach(observer => {
- observer.destroy();
- });
- utils.difference(newObservers, prevObservers).forEach(observer => {
- observer.subscribe(result => {
- this.onUpdate(observer, result);
- });
- });
- this.notify();
- });
- }
- getCurrentResult() {
- return this.result;
- }
- getQueries() {
- return this.observers.map(observer => observer.getCurrentQuery());
- }
- getObservers() {
- return this.observers;
- }
- getOptimisticResult(queries) {
- return this.findMatchingObservers(queries).map(match => match.observer.getOptimisticResult(match.defaultedQueryOptions));
- }
- findMatchingObservers(queries) {
- 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 = 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 => {
- const defaultedOptions = this.client.defaultQueryOptions(options);
- const currentObserver = this.observersMap[defaultedOptions.queryHash];
- return currentObserver != null ? currentObserver : new queryObserver.QueryObserver(this.client, defaultedOptions);
- };
- const newOrReusedObservers = 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, b) => defaultedQueryOptions.indexOf(a.defaultedQueryOptions) - defaultedQueryOptions.indexOf(b.defaultedQueryOptions);
- return matchingObservers.concat(newOrReusedObservers).sort(sortMatchesByOrderOfQueries);
- }
- onUpdate(observer, result) {
- const index = this.observers.indexOf(observer);
- if (index !== -1) {
- this.result = utils.replaceAt(this.result, index, result);
- this.notify();
- }
- }
- notify() {
- notifyManager.notifyManager.batch(() => {
- this.listeners.forEach(({
- listener
- }) => {
- listener(this.result);
- });
- });
- }
- }
- exports.QueriesObserver = QueriesObserver;
- //# sourceMappingURL=queriesObserver.js.map
|