{"id":15013345,"url":"https://github.com/peerlibrary/meteor-reactive-publish","last_synced_at":"2025-04-12T04:41:55.675Z","repository":{"id":68281857,"uuid":"42518080","full_name":"peerlibrary/meteor-reactive-publish","owner":"peerlibrary","description":"Reactive publish endpoints","archived":false,"fork":false,"pushed_at":"2022-01-17T00:59:13.000Z","size":75,"stargazers_count":125,"open_issues_count":7,"forks_count":16,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-26T00:11:44.003Z","etag":null,"topics":["ddp","ddp-publish","meteor","meteor-package","reactivity"],"latest_commit_sha":null,"homepage":"https://atmospherejs.com/peerlibrary/reactive-publish","language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peerlibrary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-09-15T12:32:25.000Z","updated_at":"2024-11-21T13:55:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"a85a980d-4e1e-4213-97a9-fd443c25a189","html_url":"https://github.com/peerlibrary/meteor-reactive-publish","commit_stats":{"total_commits":85,"total_committers":5,"mean_commits":17.0,"dds":0.09411764705882353,"last_synced_commit":"f2d91050fca1a2f6c18f31972959f6c66734f118"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-reactive-publish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-reactive-publish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-reactive-publish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerlibrary%2Fmeteor-reactive-publish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peerlibrary","download_url":"https://codeload.github.com/peerlibrary/meteor-reactive-publish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248519333,"owners_count":21117756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddp","ddp-publish","meteor","meteor-package","reactivity"],"created_at":"2024-09-24T19:44:07.865Z","updated_at":"2025-04-12T04:41:55.654Z","avatar_url":"https://github.com/peerlibrary.png","language":"CoffeeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"reactive-publish\n================\n\nThis Meteor smart package extends [publish endpoints](http://docs.meteor.com/#/full/meteor_publish)\nwith support for reactivity so that you can use\n[server-side autorun](https://github.com/peerlibrary/meteor-server-autorun) inside a publish function.\n\nAfter adding this package you can use server-side [Tracker.autorun](http://docs.meteor.com/#/full/tracker_autorun)\ninside your publish function and any published documents will be automatically correctly send to the client while your\nreactive computation will rerun when any dependency triggers invalidation. Only changes to documents between reruns\nwill be send to the client. As a rule, things work exactly as you would expect, just reactively if they are inside an `autorun`.\nYou can use any source of reactivity, like [reactive server-side MongoDB queries](https://github.com/peerlibrary/meteor-reactive-mongo)\nand reactive variables.\n\nPublish function's `this` is extended with `this.autorun` which behaves the same as `Tracker.autorun`, but you can\nreturn a cursor of array of cursors you want to publish, and `this` inside the computation function is bound to the\npublish context. Moreover, computation is automatically stopped when subscription is stopped. If you use\n`Tracker.autorun` you have to take care of this yourselves, or you can return a computation from the publish function\nto have it stopped automatically as well.\n\nServer side only.\n\nInstallation\n------------\n\n```\nmeteor add peerlibrary:reactive-publish\n```\n\nAdditional packages\n-------------------\n\n* [peerlibrary:subscription-data](https://github.com/peerlibrary/meteor-subscription-data) – Support for\n  reactive and shared subscription data context which allows you to change arguments to the publish function without\n  restarting it, and have a side channel to communicate metadata back to the subscriber as well\n\nExamples\n--------\n\nYou can make a simple publish across an one-to-many relation:\n\n```javascript\nMeteor.publish('subscribed-posts', function () {\n  this.autorun(function (computation) {\n    var user = User.findOne(this.userId, {fields: {subscribedPosts: 1}});\n    \n    return Posts.find({_id: {$in: user \u0026\u0026 user.subscribedPosts || []}});\n  });\n});\n```\n\nYou can make queries which are based on time:\n\n```javascript\nvar currentTime = new ReactiveVar(Date.now());\n\nMeteor.setInterval(function () {\n  currentTime.set(Date.now());\n}, 1000); // ms\n\nMeteor.publish('recent-posts', function () {\n  this.autorun(function (computation) {\n    return Posts.find({\n      timestamp: {\n        $exists: true,\n        $gte: currentTime.get() - (60 * 1000) // ms\n      }\n    }, {\n      sort: {\n        timestamp: 1\n      }\n    });\n  });\n});\n```\n\nYou can make complicated but reactive permission checks. For example, support user groups:\n\n```javascript\nMeteor.publish('posts', function () {\n  this.autorun(function (computation) {\n    var user = User.findOne(this.userId, {fields: {groups: 1}});\n    \n    return Posts.find({\n      $or: [{\n        'access.userId': user \u0026\u0026 user._id\n      }, {\n        'access.groupId': {\n          $in: user \u0026\u0026 user.groups || []\n        }\n      }]\n    });\n  });\n});\n```\n\nDiscussion\n----------\n\nAdding this package to your [Meteor](http://www.meteor.com/) application will make all MongoDB queries\nreactive by default (you can still specify [`reactive: false`](http://docs.meteor.com/#/full/find) to\nqueries to disable reactivity for a specific query, or use\n[`Tracker.nonreactive`](http://docs.meteor.com/#/full/tracker_nonreactive)). It will also automatically enable\n[server-side autorun](https://github.com/peerlibrary/meteor-server-autorun). All this might break some existing\nserver-side code which might not expect to be reactive. Inspect locations where your code or packages you are using\nalready (before using this package) call `Tracker.autorun` on the server. In most cases this occurs only in the code\nwhich is shared between client and server.\n\nWhile documents are send to the client only once and in later reruns of computations only changes are send,\nthe server side still has to make a new query and compute a diff what to send for every rerun, so this approach\nis suitable for reactivity which is not common, but you still want to support it. For example, queries with\nreactive permission checks often will not change during the life-time of a query because permissions change rarely.\nBut if they do, a user will see results reactively and immediately.\n\nConsider also optimizing your `autorun`s by splitting them into multiple `autorun`s or by nesting them. You can\nalso use [computed fields](https://github.com/peerlibrary/meteor-computed-field) to minimize propagation of\nreactive change.\n\nWhen using this approach to support reactive joins it is most suitable for one-to-many relations, where the \"one\" document\nchanges infrequently. For many-to-many joins consider publishing collections separately and join them on the client side.\nThe issue is that for any change for the first \"many\" documents, the computation will be invalidated and rerun to\nquery for second set of \"many\" documents. Alternatively, you can consider using [PeerDB](https://github.com/peerlibrary/meteor-peerdb)\nwhich effectively denormalizes joins across many-to-many relations and allows direct querying and publishing.\n\nFeel free to make pull requests with optimizations.\n\nNote that calling [`onStop`](http://docs.meteor.com/#/full/publish_onstop) inside a reactive computation probably does\nnot do what you want. It will register a callback to be called when the whole publication is stopped and if you are\ndoing this inside an `autorun` this means that a new callback is registered every time the computation is rerun.\nWhich can potentially add many callbacks. Moreover, they will be called only after the whole publication stops, and\nnot between computation reruns. What you probably want is to use\n[`Tracker.onInvalidate`](http://docs.meteor.com/#/full/tracker_oninvalidate) which runs when the computation itself\nis invalidated or stopped. Do notice that for reactive queries and observes inside a computation it is not needed to\nfree their resources by yourself because that will be done already automatically.\n\nAcknowledgments\n---------------\n\nThis package is based on the great work by [Diggory Blake](https://github.com/Diggsey/meteor-reactive-publish)\nwho made the first implementation.\n\nRelated projects\n----------------\n\nThere are few other similar projects trying to address similar features, but theirs APIs are cumbersome and are different\nthan what developers are used to for Meteor.\n\n* [meteor-publish-with-relations](https://github.com/tmeasday/meteor-publish-with-relations) – complicated custom API not\n  allowing to reuse existing publish functions, which means no support for custom publish with `added`/`changed`/`removed`,\n  no support for other reactive sources\n* [meteor-smart-publish](https://github.com/yeputons/meteor-smart-publish) – complicated custom way of defining\n  dependencies and works only with query cursors and not other reactive sources\n* [reywood:publish-composite](https://github.com/englue/meteor-publish-composite) – allow you to define a nested structure\n  of cursors, which get documents from higher levels in a reactive manner, but it works only with only with query cursors\n  and not custom `added`/`changed`/`removed` functions or other reactive sources\n* [copleyjk:simple-publish](https://github.com/copleykj/meteor-simple-publish) – seems similar to\n  `meteor-publish-with-relations`, but a more developed version covering more edge cases; on the other hand it\n  has the same limitations of no support for `added`/`changed`/`removed` or other reactive sources\n* [peerlibrary:related](https://github.com/peerlibrary/meteor-related) – our previous implementation with different API\n  and no reactivity support, but with support for custom `added`/`changed`/`removed` publishing\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerlibrary%2Fmeteor-reactive-publish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeerlibrary%2Fmeteor-reactive-publish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerlibrary%2Fmeteor-reactive-publish/lists"}