Code Monkey home page Code Monkey logo

meteor-publish-join's Introduction

Meteor Publish Join

Build Status Coverage Status

Publish non-reactive or aggregated values

Use Cases

This package will come in handy when you need to publish a non-reactive value or a could-be-reactive value but too expensive to obtain by normal pub/sub, like count of all document, sum of a field of all documents...

All these values could be obtained by ordinary Meteor pub/sub or with the help of other community packages. However the problem is that they do not work smoothly with a large dataset (few thousands), because, for all packages I've known, they rely on Meteor .observe and .observeChange to track for changes.

These methods are good for small dataset (few hundreds to thousand) and the result need to be published instantly. When the dataset is big and the result do not need to be published instantly but rather be updated after a certain amount of time, this package will do better.

Possible use cases:

  • Count of all documents and the number of documents is really big (more than a thousand)
  • Publish a value can only be obtained by Mongo Aggregation
  • Publish a value obtained by calling to a remote server (REST API for ex)

Install

npm install --save meteor-publish-join

Usage

Sever
import { JoinServer } from 'meteor-publish-join';

Meteor.publish('test', function(postId) {

  // Publish the number of all comments, re-run every second
  JoinServer.publish({
    context: this,
    name: 'numComments',
    interval: 1000,
    doJoin() {
      return Comment.find().count();
    },
  });

  // Publish the number of likes on a post, re-run every 5 seconds
  JoinServer.publish({
    context: this,
    name: `numLikesOfAPost${postId}`,
    interval: 1000,
    doJoin() {
      // get all likes on post and comments of post
      const value = Post.aggregate([
        // ...
      ]);

      return value[0] && value[0].totalLikes;
    },
  });

  // Publish a random value from an external API, plays well with promise, re-run every 10 seconds
  JoinServer.publish({
    context: this,
    name: 'withPromise',
    interval: 10000,
    doJoin() {
      const id = parseInt(Math.random() * 100, 10);

      return fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
        .then(res => res.json())
        .then(data => data.title)
        .catch(err => console.error(err));
    },
  });
});
Client
import { JoinClient } from 'meteor-publish-join';

const postId = 'post1';
Meteor.subscribe('test', postId);

// Get the values published within `test` publication. All these values are reactive
JoinClient.get('numComments')
JoinClient.get(`numLikesOfAPost${postId}`)
JoinClient.get('withPromise')

API

JoinServer.publish(v: Object) [Server]

Use within publication to publish a value to subscriber. Require one argument having following required fields:

  • context
    • Type: Object
    • Desc: the publication context, e.g. this inside a publication
  • name:
    • Type: String
    • Desc: name of the published value, will be used by client code to retrieve the value
  • interval
    • Type: Number
    • Desc: the interval time for a value to be re-calculate and publish, accept number in millisecond
  • doJoin:
    • Type: Function
    • Desc: the function used to calculate the published value, got run every interval amount of time. Returned value of this function will be published to subscribers. This function also plays nicely with Promise, if a promise is returned the resolved value of that promise will be published
Example
import { JoinServer } from 'meteor-publish-join';

Meteor.publish('example', function(postId) {
  // Publish the number of all comments, re-run every second
  JoinServer.publish({
    context: this,
    name: 'numComments',
    interval: 1000,
    doJoin() {
      return Comment.find().count();
    },
  });
});
Note
  • This package uses a worker runs every 500 milliseconds to check for published values which have passed their interval time and required to re-publish. Therefore the actual interval value runs from interval to interval + 500
  • The worker of this package is actually a setTimeout loop got run every 500 milliseconds. This loop is started by the first call to JoinServer.publish and is cleared when the last publication containing a JoinServer.publish is stopped

JoinClient.get(v: String) [Client]

Use in client to obtain the published values. This function is reactive, it could be used in Blaze helpers, Tracker.auto, and other computation block.

Example
import { JoinClient } from 'meteor-publish-join';

// Use in Blaze helpers
Template.hello.helpers({
  numComments() {
    return JoinClient.get('numComments');
  },
});

// Use in Tracker.autorun
Tracker.autorun(() => {
  console.log(JoinClient.get('numComments'));
});

JoinClient.has(v: String) [Client]

See if a value has been published. This function is reactive, it could be used in Blaze helpers, Tracker.auto, and other computation block.

Example
import { JoinClient } from 'meteor-publish-join';

// Use in Blaze helpers
Template.hello.helpers({
  numComments() {
    return JoinClient.has('numComments');
  },
});

// Use in Tracker.autorun
Tracker.autorun(() => {
  console.log(JoinClient.has('numComments'));
});

Todos

  • Prevent re-run a publish if the last run has not finished
  • Add max waiting time for a publish, mark the publish as finished if it passes its limit
  • Automation test
  • An indicator option to decide if it needs to re-publishing?
  • What's else?

License

MIT

meteor-publish-join's People

Contributors

nlhuykhang avatar arunoda avatar simonsimcity avatar jamielob avatar roonyh avatar lmachens avatar

Watchers

redim avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.