123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- "use strict";
- exports.__esModule = true;
- exports.createSubscription = createSubscription;
- var _batch = require("./batch");
- function createListenerCollection() {
- const batch = (0, _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: () => []
- };
- function createSubscription(store, parentSub) {
- let unsubscribe;
- let listeners = nullListeners; // Reasons to keep the subscription active
- let subscriptionsAmount = 0; // Is this specific subscription subscribed (or only nested ones?)
- let selfSubscribed = false;
- function addNestedSub(listener) {
- trySubscribe();
- const cleanupListener = listeners.subscribe(listener); // cleanup nested sub
- let removed = false;
- return () => {
- if (!removed) {
- removed = true;
- cleanupListener();
- tryUnsubscribe();
- }
- };
- }
- function notifyNestedSubs() {
- listeners.notify();
- }
- function handleChangeWrapper() {
- if (subscription.onStateChange) {
- subscription.onStateChange();
- }
- }
- function isSubscribed() {
- return selfSubscribed;
- }
- function trySubscribe() {
- subscriptionsAmount++;
- if (!unsubscribe) {
- unsubscribe = parentSub ? parentSub.addNestedSub(handleChangeWrapper) : store.subscribe(handleChangeWrapper);
- listeners = createListenerCollection();
- }
- }
- function tryUnsubscribe() {
- subscriptionsAmount--;
- if (unsubscribe && subscriptionsAmount === 0) {
- unsubscribe();
- unsubscribe = undefined;
- listeners.clear();
- listeners = nullListeners;
- }
- }
- function trySubscribeSelf() {
- if (!selfSubscribed) {
- selfSubscribed = true;
- trySubscribe();
- }
- }
- function tryUnsubscribeSelf() {
- if (selfSubscribed) {
- selfSubscribed = false;
- tryUnsubscribe();
- }
- }
- const subscription = {
- addNestedSub,
- notifyNestedSubs,
- handleChangeWrapper,
- isSubscribed,
- trySubscribe: trySubscribeSelf,
- tryUnsubscribe: tryUnsubscribeSelf,
- getListeners: () => listeners
- };
- return subscription;
- }
|