import { Tracker } from 'meteor/tracker'; import { Subscription, Unsubscribe } from 'use-subscription'; interface ISubscriptionFactory { (...args: any[]): Subscription; } export const createReactiveSubscriptionFactory = (computeCurrentValueWith: (...args: any[]) => T): ISubscriptionFactory => (...args: any[]): Subscription => { const computeCurrentValue = (): T => computeCurrentValueWith(...args); const callbacks = new Set(); let currentValue = computeCurrentValue(); let computation: Tracker.Computation | undefined; const timeout = setTimeout(() => { computation = Tracker.autorun(() => { currentValue = computeCurrentValue(); callbacks.forEach((callback) => { callback(); }); }); }, 0); return { getCurrentValue: (): T => currentValue, subscribe: (callback): Unsubscribe => { callbacks.add(callback); return (): void => { clearTimeout(timeout); callbacks.delete(callback); if (callbacks.size === 0) { computation?.stop(); } }; }, }; };