You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							127 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
	
	
							127 lines
						
					
					
						
							2.6 KiB
						
					
					
				import { getBatch } from './batch'; // encapsulates the subscription logic for connecting a component to the redux store, as
 | 
						|
// well as nesting subscriptions of descendant components, so that we can ensure the
 | 
						|
// ancestor components re-render before descendants
 | 
						|
 | 
						|
function createListenerCollection() {
 | 
						|
  const batch = getBatch();
 | 
						|
  let first = null;
 | 
						|
  let last = null;
 | 
						|
  return {
 | 
						|
    clear() {
 | 
						|
      first = null;
 | 
						|
      last = null;
 | 
						|
    },
 | 
						|
 | 
						|
    notify() {
 | 
						|
      batch(() => {
 | 
						|
        let listener = first;
 | 
						|
 | 
						|
        while (listener) {
 | 
						|
          listener.callback();
 | 
						|
          listener = listener.next;
 | 
						|
        }
 | 
						|
      });
 | 
						|
    },
 | 
						|
 | 
						|
    get() {
 | 
						|
      let listeners = [];
 | 
						|
      let listener = first;
 | 
						|
 | 
						|
      while (listener) {
 | 
						|
        listeners.push(listener);
 | 
						|
        listener = listener.next;
 | 
						|
      }
 | 
						|
 | 
						|
      return listeners;
 | 
						|
    },
 | 
						|
 | 
						|
    subscribe(callback) {
 | 
						|
      let isSubscribed = true;
 | 
						|
      let listener = last = {
 | 
						|
        callback,
 | 
						|
        next: null,
 | 
						|
        prev: last
 | 
						|
      };
 | 
						|
 | 
						|
      if (listener.prev) {
 | 
						|
        listener.prev.next = listener;
 | 
						|
      } else {
 | 
						|
        first = listener;
 | 
						|
      }
 | 
						|
 | 
						|
      return function unsubscribe() {
 | 
						|
        if (!isSubscribed || first === null) return;
 | 
						|
        isSubscribed = false;
 | 
						|
 | 
						|
        if (listener.next) {
 | 
						|
          listener.next.prev = listener.prev;
 | 
						|
        } else {
 | 
						|
          last = listener.prev;
 | 
						|
        }
 | 
						|
 | 
						|
        if (listener.prev) {
 | 
						|
          listener.prev.next = listener.next;
 | 
						|
        } else {
 | 
						|
          first = listener.next;
 | 
						|
        }
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
const nullListeners = {
 | 
						|
  notify() {},
 | 
						|
 | 
						|
  get: () => []
 | 
						|
};
 | 
						|
export function createSubscription(store, parentSub) {
 | 
						|
  let unsubscribe;
 | 
						|
  let listeners = nullListeners;
 | 
						|
 | 
						|
  function addNestedSub(listener) {
 | 
						|
    trySubscribe();
 | 
						|
    return listeners.subscribe(listener);
 | 
						|
  }
 | 
						|
 | 
						|
  function notifyNestedSubs() {
 | 
						|
    listeners.notify();
 | 
						|
  }
 | 
						|
 | 
						|
  function handleChangeWrapper() {
 | 
						|
    if (subscription.onStateChange) {
 | 
						|
      subscription.onStateChange();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function isSubscribed() {
 | 
						|
    return Boolean(unsubscribe);
 | 
						|
  }
 | 
						|
 | 
						|
  function trySubscribe() {
 | 
						|
    if (!unsubscribe) {
 | 
						|
      unsubscribe = parentSub ? parentSub.addNestedSub(handleChangeWrapper) : store.subscribe(handleChangeWrapper);
 | 
						|
      listeners = createListenerCollection();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function tryUnsubscribe() {
 | 
						|
    if (unsubscribe) {
 | 
						|
      unsubscribe();
 | 
						|
      unsubscribe = undefined;
 | 
						|
      listeners.clear();
 | 
						|
      listeners = nullListeners;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const subscription = {
 | 
						|
    addNestedSub,
 | 
						|
    notifyNestedSubs,
 | 
						|
    handleChangeWrapper,
 | 
						|
    isSubscribed,
 | 
						|
    trySubscribe,
 | 
						|
    tryUnsubscribe,
 | 
						|
    getListeners: () => listeners
 | 
						|
  };
 | 
						|
  return subscription;
 | 
						|
} |