Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autoSubscribe: only stop subscriptions if the arguments change #11

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nathan-muir
Copy link

Given a simple usage of autoSubscribe such as:

<script setup>
import { useRoute } from 'vue-router'
import { autoSubscribe } from 'meteor/vuejs:vue3'
const route = useRoute();

autoSubscribe(() => ['publicationName', route.params.id])
</script>

Currently, each time the route changes/invalidates, even if the route.params.id does not change, it will send an "unsub" and "sub" message to the meteor server. Causing the publication to be re-run on the server using additional (unnecessary) resources.

The solution is to copy the pattern from the built-in meteor/ddp-client subscribe function, where it integrates with Tracker.

Here is the relevant code:

class DDPClient {

  subscribe(...) {
      /* ... */
    if (Tracker.active) {
      // We're in a reactive computation, so we'd like to unsubscribe when the
      // computation is invalidated... but not if the rerun just re-subscribes
      // to the same subscription!  When a rerun happens, we use onInvalidate
      // as a change to mark the subscription "inactive" so that it can
      // be reused from the rerun.  If it isn't reused, it's killed from
      // an afterFlush.
      Tracker.onInvalidate((c) => {
        if (hasOwn.call(self._subscriptions, id)) {
          self._subscriptions[id].inactive = true;
        }

        Tracker.afterFlush(() => {
          if (hasOwn.call(self._subscriptions, id) &&
              self._subscriptions[id].inactive) {
            handle.stop();
          }
        });
      });
    }
  }
}

This pull request attempts to approximate Tracker.afterFlush by using Promise.resolve(); I'm not aware if there's a better method for vue reactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant