reactive-publish
reactive-publish
is a Meteor package that adds reactive publishing with async support. It's based on peerlibrary:reactive-publish, fully overhauled for compatibility with Meteor 3 and its fiber-free environment.
-
π Reactively publish data with related field changes across collections
-
βοΈ Supports
autorun
in publication functions for realtime updates -
π§΅ Integrates
AsyncTracker
andReactiveVarAsync
for async-compatible reactivity -
π Optimized with unique cursors per computation to avoid redundant re-instantiation
π₯ Learn about the motivation for reviving this package for Meteor 3.
πΊοΈ Explore the roadmap for future updates and support.
Installation
meteor add nachocodoner:reactive-publish@1.0.0-alpha.0
Usage
Basic
1Meteor.publish('subscribed-posts', function () { 2 this.autorun(async () => { 3 const user = await User.findOneAsync(this.userId, { 4 fields: { subscribedPosts: 1 }, 5 }); 6 7 return Posts.find({ _id: { $in: user?.subscribedPosts || [] } }); 8 }); 9});
Since most use cases involve a single autorun
block, you can use Meteor.publishReactive
for cleaner syntax:
1Meteor.publishReactive('subscribed-posts', async function () { 2 const user = await User.findOneAsync(this.userId, { 3 fields: { subscribedPosts: 1 }, 4 }); 5 6 return Posts.find({ _id: { $in: user?.subscribedPosts || [] } }); 7});
Time-based queries
1import { ReactiveVarAsync } from 'meteor/nachocodoner:reactive-publish'; 2 3const currentTime = new ReactiveVarAsync(Date.now()); 4 5Meteor.setInterval(() => { 6 currentTime.set(Date.now()); 7}, 1000); // ms 8 9Meteor.publish('recent-posts', function () { 10 this.autorun(() => { 11 return Posts.find({ 12 timestamp: { 13 $exists: true, 14 $gte: currentTime.get() - 60 * 1000, 15 }, 16 }, { 17 sort: { timestamp: 1 }, 18 }); 19 }); 20});
Multiple autoruns
1Meteor.publish('users-posts-and-addresses', function (userId) { 2 this.autorun(async () => { 3 const user = await Users.findOneAsync(userId, { 4 fields: { posts: 1 }, 5 }); 6 return Posts.find({ _id: { $in: user?.posts || [] } }); 7 }); 8 9 this.autorun(async () => { 10 const user = await Users.findOneAsync(userId, { 11 fields: { addresses: 1 }, 12 }); 13 return Addresses.find({ _id: { $in: user?.addresses || [] } }); 14 }); 15});
Roadmap
-
Stability
- Ensure core changes in this package don't affect Meteor core tests
- Release betas and RCs, with a feedback period for early adopters
-
Expansion
- Support for
AsyncTracker
andReactiveVarAsync
on the client - Migrate
peerlibrary/meteor-subscription-data
to support publishing derived or external database data reactively
- Support for
-
Performance
- Run benchmarks to identify performance improvement opportunities
- Compare results with
reywood:publish-composite
to ensure equal or better behavior
Acknowledgments
This package builds on over a decade of work by PeerLibrary during the legacy Meteor era. Big thanks to everyone involved over those years, , especially mitar.
The original idea came from the excellent work of Diggory Blake, who created the first implementation.