Subscription.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.createSubscription = createSubscription;
  4. var _batch = require("./batch");
  5. // encapsulates the subscription logic for connecting a component to the redux store, as
  6. // well as nesting subscriptions of descendant components, so that we can ensure the
  7. // ancestor components re-render before descendants
  8. function createListenerCollection() {
  9. var batch = (0, _batch.getBatch)();
  10. var first = null;
  11. var last = null;
  12. return {
  13. clear: function clear() {
  14. first = null;
  15. last = null;
  16. },
  17. notify: function notify() {
  18. batch(function () {
  19. var listener = first;
  20. while (listener) {
  21. listener.callback();
  22. listener = listener.next;
  23. }
  24. });
  25. },
  26. get: function get() {
  27. var listeners = [];
  28. var listener = first;
  29. while (listener) {
  30. listeners.push(listener);
  31. listener = listener.next;
  32. }
  33. return listeners;
  34. },
  35. subscribe: function subscribe(callback) {
  36. var isSubscribed = true;
  37. var listener = last = {
  38. callback: callback,
  39. next: null,
  40. prev: last
  41. };
  42. if (listener.prev) {
  43. listener.prev.next = listener;
  44. } else {
  45. first = listener;
  46. }
  47. return function unsubscribe() {
  48. if (!isSubscribed || first === null) return;
  49. isSubscribed = false;
  50. if (listener.next) {
  51. listener.next.prev = listener.prev;
  52. } else {
  53. last = listener.prev;
  54. }
  55. if (listener.prev) {
  56. listener.prev.next = listener.next;
  57. } else {
  58. first = listener.next;
  59. }
  60. };
  61. }
  62. };
  63. }
  64. var nullListeners = {
  65. notify: function notify() {},
  66. get: function get() {
  67. return [];
  68. }
  69. };
  70. function createSubscription(store, parentSub) {
  71. var unsubscribe;
  72. var listeners = nullListeners;
  73. function addNestedSub(listener) {
  74. trySubscribe();
  75. return listeners.subscribe(listener);
  76. }
  77. function notifyNestedSubs() {
  78. listeners.notify();
  79. }
  80. function handleChangeWrapper() {
  81. if (subscription.onStateChange) {
  82. subscription.onStateChange();
  83. }
  84. }
  85. function isSubscribed() {
  86. return Boolean(unsubscribe);
  87. }
  88. function trySubscribe() {
  89. if (!unsubscribe) {
  90. unsubscribe = parentSub ? parentSub.addNestedSub(handleChangeWrapper) : store.subscribe(handleChangeWrapper);
  91. listeners = createListenerCollection();
  92. }
  93. }
  94. function tryUnsubscribe() {
  95. if (unsubscribe) {
  96. unsubscribe();
  97. unsubscribe = undefined;
  98. listeners.clear();
  99. listeners = nullListeners;
  100. }
  101. }
  102. var subscription = {
  103. addNestedSub: addNestedSub,
  104. notifyNestedSubs: notifyNestedSubs,
  105. handleChangeWrapper: handleChangeWrapper,
  106. isSubscribed: isSubscribed,
  107. trySubscribe: trySubscribe,
  108. tryUnsubscribe: tryUnsubscribe,
  109. getListeners: function getListeners() {
  110. return listeners;
  111. }
  112. };
  113. return subscription;
  114. }