nachocodoner:reactive-publish

v1.0.0-alpha.0β€’Published last month

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 and ReactiveVarAsync 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

  • Performance

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.