forked from rdb/svelte-meteor-data
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubscribe.js
61 lines (55 loc) · 1.7 KB
/
subscribe.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
/**
* Overrides Meteor.subscribe to do the following things:
* - Automatically stops the subscription when the component is destroyed
* - Makes the return value usable in {#await} blocks
*/
import { current_component } from 'svelte/internal';
_subscribe = Meteor.subscribe;
Meteor.subscribe = function subscribe(name) {
const params = Array.from(arguments);
let callbacks = Object.create(null);
if (params.length > 1) {
// Preserve existing callbacks.
const last = params[params.length - 1];
if (last) {
// Last arg may be specified as a function, or as an object
if (typeof last === 'function') {
callbacks.onReady = params.pop();
} else if ([last.onReady, last.onError, last.onStop].some(f => typeof f === "function")) {
callbacks = params.pop();
}
}
}
params.push(callbacks);
let subscription;
// Collect callbacks to call when subscription is ready or has errored.
let readyCallbacks = [];
let errorCallbacks = [];
if (callbacks.onReady) {
readyCallbacks.push(callbacks.onReady);
}
if (callbacks.onError) {
errorCallbacks.push(callbacks.onError);
}
callbacks.onReady = () => {
readyCallbacks.forEach(fn => fn(subscription));
readyCallbacks.length = 0;
};
callbacks.onError = (err) => {
errorCallbacks.forEach(fn => fn(err));
errorCallbacks.length = 0;
};
subscription = _subscribe.apply(this, params);
if (current_component) {
current_component.$$.on_destroy.push(subscription.stop.bind(subscription));
}
subscription.then = (fn, err) => {
if (subscription.ready()) {
fn();
} else {
readyCallbacks.push(fn);
err && errorCallbacks.push(err);
}
};
return subscription;
};