All Projects → peerlibrary → Meteor Reactive Publish

peerlibrary / Meteor Reactive Publish

Licence: bsd-3-clause
Reactive publish endpoints

Programming Languages

coffeescript
4710 projects

Projects that are alternatives of or similar to Meteor Reactive Publish

Meteor Blaze Components
Reusable components for Blaze
Stars: ✭ 361 (+193.5%)
Mutual labels:  meteor, meteor-package
Meteor Transactions
App level transactions for Meteor + Mongo
Stars: ✭ 115 (-6.5%)
Mutual labels:  meteor, meteor-package
Meteor Easy Search
Easy-to-use search for Meteor with Blaze Components
Stars: ✭ 438 (+256.1%)
Mutual labels:  meteor, meteor-package
meteor-spacebars-tohtml
Meteor package to ease rendering spacebars to html
Stars: ✭ 35 (-71.54%)
Mutual labels:  meteor, meteor-package
Autocms
AutoCms is a simple solution for your Meteor.js app
Stars: ✭ 34 (-72.36%)
Mutual labels:  meteor, meteor-package
awesome-blaze
🔥A curated list of awesome things related to Blaze
Stars: ✭ 29 (-76.42%)
Mutual labels:  meteor, meteor-package
Meteor Collection Helpers
⚙️ Meteor package that allows you to define helpers on your collections
Stars: ✭ 504 (+309.76%)
Mutual labels:  meteor, meteor-package
Meteor-logger
🧾 Meteor isomorphic logger. Store application logs in File (FS), MongoDB, or print in Console
Stars: ✭ 51 (-58.54%)
Mutual labels:  meteor, meteor-package
Ostrio Analytics
📊 Visitor's analytics tracking code for ostr.io service
Stars: ✭ 9 (-92.68%)
Mutual labels:  meteor, meteor-package
Mongol Meteor Explore Minimongo Devtools
In-App MongoDB Editor for Meteor (Meteor DevTools)
Stars: ✭ 846 (+587.8%)
Mutual labels:  meteor, meteor-package
meteor-presence
👥 Meteor package to help track users' presence
Stars: ✭ 88 (-28.46%)
Mutual labels:  meteor, meteor-package
Ostrio Neo4jdriver
Most advanced and efficient Neo4j REST API Driver, with support of https and GrapheneDB
Stars: ✭ 55 (-55.28%)
Mutual labels:  meteor, meteor-package
svelte-meteor-data
Reactively track Meteor data inside Svelte components
Stars: ✭ 14 (-88.62%)
Mutual labels:  meteor, meteor-package
spiderable-middleware
🤖 Prerendering for JavaScript powered websites. Great solution for PWAs (Progressive Web Apps), SPAs (Single Page Applications), and other websites based on top of front-end JavaScript frameworks
Stars: ✭ 29 (-76.42%)
Mutual labels:  meteor, meteor-package
meteor-flow-router-map
Meteor package for Flow Router
Stars: ✭ 15 (-87.8%)
Mutual labels:  meteor, meteor-package
Blaze
🔥 Meteor Blaze is a powerful library for creating live-updating user interfaces
Stars: ✭ 474 (+285.37%)
Mutual labels:  meteor, meteor-package
meteor-control-mergebox
Control mergebox of publish endpoints
Stars: ✭ 28 (-77.24%)
Mutual labels:  meteor, meteor-package
meteor-server-autorun
Server-side Tracker.autorun
Stars: ✭ 36 (-70.73%)
Mutual labels:  meteor, meteor-package
Vue Meteor
🌠 Vue first-class integration in Meteor
Stars: ✭ 893 (+626.02%)
Mutual labels:  meteor, meteor-package
Meteor Files
🚀 Upload files via DDP or HTTP to ☄️ Meteor server FS, AWS, GridFS, DropBox or Google Drive. Fast, secure and robust.
Stars: ✭ 1,033 (+739.84%)
Mutual labels:  meteor, meteor-package

reactive-publish

This Meteor smart package extends publish endpoints with support for reactivity so that you can use server-side autorun inside a publish function.

After adding this package you can use server-side Tracker.autorun inside your publish function and any published documents will be automatically correctly send to the client while your reactive computation will rerun when any dependency triggers invalidation. Only changes to documents between reruns will be send to the client. As a rule, things work exactly as you would expect, just reactively if they are inside an autorun. You can use any source of reactivity, like reactive server-side MongoDB queries and reactive variables.

Publish function's this is extended with this.autorun which behaves the same as Tracker.autorun, but you can return a cursor of array of cursors you want to publish, and this inside the computation function is bound to the publish context. Moreover, computation is automatically stopped when subscription is stopped. If you use Tracker.autorun you have to take care of this yourselves, or you can return a computation from the publish function to have it stopped automatically as well.

Server side only.

Installation

meteor add peerlibrary:reactive-publish

Additional packages

  • peerlibrary:subscription-data – Support for reactive and shared subscription data context which allows you to change arguments to the publish function without restarting it, and have a side channel to communicate metadata back to the subscriber as well

Examples

You can make a simple publish across an one-to-many relation:

Meteor.publish('subscribed-posts', function () {
  this.autorun(function (computation) {
    var user = User.findOne(this.userId, {fields: {subscribedPosts: 1}});
    
    return Posts.find({_id: {$in: user && user.subscribedPosts || []}});
  });
});

You can make queries which are based on time:

var currentTime = new ReactiveVar(Date.now());

Meteor.setInterval(function () {
  currentTime.set(Date.now());
}, 1000); // ms

Meteor.publish('recent-posts', function () {
  this.autorun(function (computation) {
    return Posts.find({
      timestamp: {
        $exists: true,
        $gte: currentTime.get() - (60 * 1000) // ms
      }
    }, {
      sort: {
        timestamp: 1
      }
    });
  });
});

You can make complicated but reactive permission checks. For example, support user groups:

Meteor.publish('posts', function () {
  this.autorun(function (computation) {
    var user = User.findOne(this.userId, {fields: {groups: 1}});
    
    return Posts.find({
      $or: [{
        'access.userId': user && user._id
      }, {
        'access.groupId': {
          $in: user && user.groups || []
        }
      }]
    });
  });
});

Discussion

Adding this package to your Meteor application will make all MongoDB queries reactive by default (you can still specify reactive: false to queries to disable reactivity for a specific query, or use Tracker.nonreactive). It will also automatically enable server-side autorun. All this might break some existing server-side code which might not expect to be reactive. Inspect locations where your code or packages you are using already (before using this package) call Tracker.autorun on the server. In most cases this occurs only in the code which is shared between client and server.

While documents are send to the client only once and in later reruns of computations only changes are send, the server side still has to make a new query and compute a diff what to send for every rerun, so this approach is suitable for reactivity which is not common, but you still want to support it. For example, queries with reactive permission checks often will not change during the life-time of a query because permissions change rarely. But if they do, a user will see results reactively and immediately.

Consider also optimizing your autoruns by splitting them into multiple autoruns or by nesting them. You can also use computed fields to minimize propagation of reactive change.

When using this approach to support reactive joins it is most suitable for one-to-many relations, where the "one" document changes infrequently. For many-to-many joins consider publishing collections separately and join them on the client side. The issue is that for any change for the first "many" documents, the computation will be invalidated and rerun to query for second set of "many" documents. Alternatively, you can consider using PeerDB which effectively denormalizes joins across many-to-many relations and allows direct querying and publishing.

Feel free to make pull requests with optimizations.

Note that calling onStop inside a reactive computation probably does not do what you want. It will register a callback to be called when the whole publication is stopped and if you are doing this inside an autorun this means that a new callback is registered every time the computation is rerun. Which can potentially add many callbacks. Moreover, they will be called only after the whole publication stops, and not between computation reruns. What you probably want is to use Tracker.onInvalidate which runs when the computation itself is invalidated or stopped. Do notice that for reactive queries and observes inside a computation it is not needed to free their resources by yourself because that will be done already automatically.

Acknowledgments

This package is based on the great work by Diggory Blake who made the first implementation.

Related projects

There are few other similar projects trying to address similar features, but theirs APIs are cumbersome and are different than what developers are used to for Meteor.

  • meteor-publish-with-relations – complicated custom API not allowing to reuse existing publish functions, which means no support for custom publish with added/changed/removed, no support for other reactive sources
  • meteor-smart-publish – complicated custom way of defining dependencies and works only with query cursors and not other reactive sources
  • reywood:publish-composite – allow you to define a nested structure of cursors, which get documents from higher levels in a reactive manner, but it works only with only with query cursors and not custom added/changed/removed functions or other reactive sources
  • copleyjk:simple-publish – seems similar to meteor-publish-with-relations, but a more developed version covering more edge cases; on the other hand it has the same limitations of no support for added/changed/removed or other reactive sources
  • peerlibrary:related – our previous implementation with different API and no reactivity support, but with support for custom added/changed/removed publishing
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].