This repository has been archived by the owner on Jan 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 25
/
meteorSubscription.js
73 lines (64 loc) · 1.97 KB
/
meteorSubscription.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* global Meteor, Tracker */
import actionTypeBuilder from '../actions/actionTypeBuilder';
const handles = [];
const computations = [];
/* This middleware is used for Meteor subscriptions. It'll handle actions
* containing a meteor object such as:
*
* const MY_SUBSCRIPTION = 'MY_SUBSCRIPTION';
*
* export function myAction (param1, param2) {
* return dispatch => {
* dispatch(myOnLoadingAction());
*
* return {
* type: MY_SUBSCRIPTION,
* meteor: {
* subscribe: () => Meteor.subscribe('mysubscription', param1, param2),
* get: () => MyCollection.find(),
* }
* }
* }
* }
*
* If you dispatch the same action more than one time with the same type, it will
* stop and reload the subscription.
*
* It will dispatch a 'MY_SUBSCRIPTION_READY' action whenever the subscription.ready recompute.
* The action will have a 'ready' property.
*
* It will dispatch a 'MY_SUBSCRIPTION_CHANGED' action when the subscription data change.
* The action will have a 'data' property containing whatever your 'get' function returns.
*/
export default store => next => action => {
if (!action.meteor || !action.meteor.subscribe) {
return next(action);
}
const { subscribe, get, onChange } = action.meteor;
// If we already have an handle for this action
if (handles[action.type]) {
const subscriptionId = handles[action.type].subscriptionId;
computations[subscriptionId].stop();
handles[action.type].stop();
}
const handle = subscribe();
const subscriptionId = handle.subscriptionId;
handles[action.type] = handle;
computations[subscriptionId] = Tracker.autorun(() => {
const data = get();
const ready = handle.ready();
store.dispatch({
type: actionTypeBuilder.ready(action.type),
ready,
});
if (ready) {
if (onChange) {
onChange(data);
}
store.dispatch({
type: actionTypeBuilder.changed(action.type),
data,
});
}
});
};