@mexin thanks for the interest. Here is a quick working approach.
First we define a new collection on server and client. It will contain the maxCount for a publication, per connection
Meteor.collection_count = new Meteor.Collection("collection_count");
On the client we subscribe to the collection-count publication, doesn’t matter if logged in or not, because it is per connection
Meteor.subscribe('collection_count');
On server side we add the following
// publish the collection_count per connection id
Meteor.publish('collection_count', function () {
const self = this;
return Meteor.collection_count.find({ connectionId: self.connection.id });
});
// make sure we clean up when the connection drops
Meteor.onConnection(function (connection) {
const connectionId = connection.id;
connection.onClose(function () {
let c = Meteor.collection_count.remove({ connectionId: connectionId });
if (Meteor.isDevelopment) console.log(`onClose ${connectionId} removed ${c}`);
});
});
Meteor.startup(function () {
//
// clear collection_count when server starts
//
Meteor.collection_count.remove({});
Meteor.collection_count._ensureIndex({ connectionId: 1 });
});
// add function to do the collection count
Meteor.collectionCount = (subscription, cursor) => {
check(subscription?.constructor?.name, 'Subscription');
check(cursor?.constructor?.name, 'Cursor');
const connectionId = subscription.connection.id;
const subscriptionName = subscription._name;
const cursorDescription = cursor._cursorDescription;
const collectionName = cursorDescription.collectionName;
const db = cursor._mongo.db;
const collections = db.collections().await();
const collection = collections.filter((c) => {return c.s.name == collectionName});
const maxCount = collection.length == 1 ? collection[0].find(cursorDescription.selector).count().await() : -1;
console.log(`Meteor.CollectionCount ${subscriptionName} ${connectionId}`, maxCount);
Meteor.collection_count.upsert({ connectionId: connectionId, subscriptionName: subscriptionName }, { connectionId: connectionId, subscriptionName: subscriptionName, maxCount: maxCount })
return cursor;
}
Now we can use this function in our publications
Meteor.publish('items', function(query={}, skip=0){
const self = this;
return Meteor.collectionCount(self, Items.find(query, {
limit:10,
skip: skip,
sort:{number:1}
}));
});
On the client we can simply query this collection
Template.items.onCreated(function(){
const instance = this;
instance.skip = 0
instance.subscribe('items', instance.skip);
instance.autorun(function(){
const c = Meteor.collection_count.findOne({ subscriptionName: 'items' });
console.log(`items maxCount = ${c?.maxCount}`);
})
});
I’m pretty sure this can be improved upon by someone with better coding skills.
Edit: I just created a new package meteor show jamgold:meteor-collection-count