Last active
September 3, 2018 12:53
-
-
Save vadym-vorobel/3fa40f8122a219c52692c290efa58ffe to your computer and use it in GitHub Desktop.
Manager that helps to work with Meteor subscriptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Template } from 'meteor/templating'; | |
import initSubsManager from './subs-manager'; | |
const subsManager = initSubsManager(); | |
// you can show subs manager logs with debug mode | |
// subsManager.debug(); | |
Template.example.onCreated(function () { | |
subsManager.add(this.subscribe('subs.one')); | |
subsManager.add(this.subscribe('subs.two')); | |
}); | |
Template.example.helpers({ | |
subsReady() { | |
return subsManager.ready(); | |
}, | |
}); | |
Template.example.onDestroyed(function () { | |
// you may stop subscription by it's name if you need | |
subsManager.stop('subs.one'); | |
// or stop them all | |
subsManager.stop(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Meteor } from 'meteor/meteor'; | |
import { withTracker } from 'meteor/react-meteor-data'; | |
import initSubsManager from '/imports/utility/subs-manager'; | |
// your Mongo collection here | |
import Collection from '/imports/api/collection'; | |
// your React component here | |
import ExampleComponent from './ExampleComponent'; | |
const subsManager = getSubsManager(); | |
export default withTracker(({ arg1, arg2 }) => { | |
const subsHandler = Meteor.subscribe('subs.one', { arg1, arg2 }); | |
subsManager.add(subsHandler); | |
const data = Collection.find().fetch(); | |
return { | |
data, | |
loading: !subsHandler.ready(), | |
// need to bind | |
onComponentUnmount: subsManager.stop.bind(subsManager), | |
}; | |
})(ExampleComponent); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-console, no-underscore-dangle */ | |
import { Meteor } from 'meteor/meteor'; | |
import { Tracker } from 'meteor/tracker'; | |
const getMeteorSubscriptions = () => Meteor.default_connection._subscriptions; | |
const getMockSubscription = subscriptionId => ({ | |
_id: subscriptionId, | |
name: 'Unnamed subscription', | |
ready: true, | |
stop: () => true, | |
newSubscription: true, | |
}); | |
const getSubscriptionById = ({ subscriptionId }) => { | |
const subscriptions = getMeteorSubscriptions(); | |
return subscriptions[subscriptionId] || getMockSubscription(subscriptionId); | |
}; | |
const getSubscriptionByName = (subscriptionName) => { | |
const subscriptions = getMeteorSubscriptions(); | |
const subscription = Object.values(subscriptions).find(({ name }) => name === subscriptionName); | |
return subscription || getMockSubscription(null); | |
}; | |
export default () => { | |
// provide reactivity to the subs manager | |
const dep = new Tracker.Dependency(); | |
return { | |
_debugMode: false, | |
subscriptions: [], | |
add(subscription) { | |
// check whether the subscription already exists | |
const subsExists = this._checkSubscriptionExists(subscription); | |
// don't add existing subs one more time | |
if (!subsExists) { | |
const subsInfo = getSubscriptionById(subscription); | |
this._log(`Added subscription "${subsInfo.name}" (${subsInfo.id})`); | |
this.subscriptions = this.subscriptions.concat(subscription); | |
} | |
dep.changed(); | |
}, | |
ready() { | |
dep.depend(); | |
// ready if there are no subscriptions | |
if (this.subscriptions.length === 0) { | |
return true; | |
} | |
if (!this._debugMode) { | |
return this.subscriptions.every(subscription => subscription.ready); | |
} | |
const allSubsReady = this.subscriptions.every((subscription) => { | |
const { ready: isSubsReady } = subscription; | |
const subsInfo = getSubscriptionById(subscription); | |
// eslint-disable-next-line | |
this._log( | |
`Subscription "${subsInfo.name}" (${subsInfo.id}): ${isSubsReady ? 'READY' : 'NOT READY'}` | |
); | |
return isSubsReady; | |
}); | |
this._log(allSubsReady ? 'All subs are ready' : 'Not all subs are ready'); | |
return allSubsReady; | |
}, | |
stop(subscriptionName) { | |
if (subscriptionName) { | |
const subscriptionToStop = getSubscriptionByName(subscriptionName); | |
this._log(`Stopping subscription ${subscriptionName} (${subscriptionToStop.id})`); | |
subscriptionToStop.stop(); | |
this.subscriptions.filter(({ subscriptionId }) => subscriptionId !== subscriptionToStop.id); | |
this._log(`Subscription ${subscriptionName} stopped`); | |
} else { | |
this._log('Stopping subscriptions'); | |
this.subscriptions.forEach(subscription => subscription.stop()); | |
this.subscriptions = []; | |
this._log('All subscriptions stopped'); | |
} | |
dep.changed(); | |
}, | |
debug() { | |
this._debugMode = true; | |
}, | |
_log(message) { | |
if (this._debugMode) { | |
console.log(`[SubsManager]: ${message}`); | |
} | |
}, | |
_checkSubscriptionExists({ subscriptionId }) { | |
return this.subscriptions.findIndex(({ subscriptionId: id }) => subscriptionId === id) > -1; | |
}, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment