96 lines
2.6 KiB
JavaScript
96 lines
2.6 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
|
||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
|
||
|
// 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
|
||
|
|
||
|
var CLEARED = null;
|
||
|
var nullListeners = {
|
||
|
notify: function notify() {}
|
||
|
};
|
||
|
|
||
|
function createListenerCollection() {
|
||
|
// the current/next pattern is copied from redux's createStore code.
|
||
|
// TODO: refactor+expose that code to be reusable here?
|
||
|
var current = [];
|
||
|
var next = [];
|
||
|
|
||
|
return {
|
||
|
clear: function clear() {
|
||
|
next = CLEARED;
|
||
|
current = CLEARED;
|
||
|
},
|
||
|
notify: function notify() {
|
||
|
var listeners = current = next;
|
||
|
for (var i = 0; i < listeners.length; i++) {
|
||
|
listeners[i]();
|
||
|
}
|
||
|
},
|
||
|
get: function get() {
|
||
|
return next;
|
||
|
},
|
||
|
subscribe: function subscribe(listener) {
|
||
|
var isSubscribed = true;
|
||
|
if (next === current) next = current.slice();
|
||
|
next.push(listener);
|
||
|
|
||
|
return function unsubscribe() {
|
||
|
if (!isSubscribed || current === CLEARED) return;
|
||
|
isSubscribed = false;
|
||
|
|
||
|
if (next === current) next = current.slice();
|
||
|
next.splice(next.indexOf(listener), 1);
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
var Subscription = function () {
|
||
|
function Subscription(store, parentSub, onStateChange) {
|
||
|
_classCallCheck(this, Subscription);
|
||
|
|
||
|
this.store = store;
|
||
|
this.parentSub = parentSub;
|
||
|
this.onStateChange = onStateChange;
|
||
|
this.unsubscribe = null;
|
||
|
this.listeners = nullListeners;
|
||
|
}
|
||
|
|
||
|
Subscription.prototype.addNestedSub = function addNestedSub(listener) {
|
||
|
this.trySubscribe();
|
||
|
return this.listeners.subscribe(listener);
|
||
|
};
|
||
|
|
||
|
Subscription.prototype.notifyNestedSubs = function notifyNestedSubs() {
|
||
|
this.listeners.notify();
|
||
|
};
|
||
|
|
||
|
Subscription.prototype.isSubscribed = function isSubscribed() {
|
||
|
return Boolean(this.unsubscribe);
|
||
|
};
|
||
|
|
||
|
Subscription.prototype.trySubscribe = function trySubscribe() {
|
||
|
if (!this.unsubscribe) {
|
||
|
this.unsubscribe = this.parentSub ? this.parentSub.addNestedSub(this.onStateChange) : this.store.subscribe(this.onStateChange);
|
||
|
|
||
|
this.listeners = createListenerCollection();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Subscription.prototype.tryUnsubscribe = function tryUnsubscribe() {
|
||
|
if (this.unsubscribe) {
|
||
|
this.unsubscribe();
|
||
|
this.unsubscribe = null;
|
||
|
this.listeners.clear();
|
||
|
this.listeners = nullListeners;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
return Subscription;
|
||
|
}();
|
||
|
|
||
|
exports.default = Subscription;
|