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() { var batch = getBatch(); var first = null; var last = null; return { clear: function clear() { first = null; last = null; }, notify: function notify() { batch(function () { var listener = first; while (listener) { listener.callback(); listener = listener.next; } }); }, get: function get() { var listeners = []; var listener = first; while (listener) { listeners.push(listener); listener = listener.next; } return listeners; }, subscribe: function subscribe(callback) { var isSubscribed = true; var listener = last = { callback: 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; } }; } }; } var nullListeners = { notify: function notify() {}, get: function get() { return []; } }; export function createSubscription(store, parentSub) { var unsubscribe; var 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; } } var subscription = { addNestedSub: addNestedSub, notifyNestedSubs: notifyNestedSubs, handleChangeWrapper: handleChangeWrapper, isSubscribed: isSubscribed, trySubscribe: trySubscribe, tryUnsubscribe: tryUnsubscribe, getListeners: function getListeners() { return listeners; } }; return subscription; }