@stackoverfloweth/vue-compositions
Version:
A collection of reusable vue compositions.
56 lines • 2.91 kB
JavaScript
import { reactive, unref } from 'vue';
import { SubscriptionManager } from '../useSubscription/models';
import { mapSubscription } from '../useSubscription/utilities/subscriptions';
import { getValidWatchSource } from '../utilities/getValidWatchSource';
import { tryOnScopeDispose } from '../utilities/tryOnScopeDispose';
import { uniqueValueWatcher } from '../utilities/uniqueValueWatcher';
export const defaultSubscriptionManager = new SubscriptionManager();
/**
* The `useSubscription` composition manages data sharing across components. Multiple components can subscribe to an `action` (any method or function) and share the response value.
*
* @see [docs](https://github.com/PrefectHQ/vue-compositions/tree/main/src/useSubscription#readme)
*
* @param action - The function to be executed.
* @param args - Parameters of the action being executed.
*/
export function useSubscription(...[action, args, optionsArg = {}]) {
const options = unref(optionsArg);
const manager = options.manager ?? defaultSubscriptionManager;
const argsWithDefault = args ?? [];
const originalSubscription = manager.subscribe(action, argsWithDefault, options);
const subscriptionResponse = reactive(mapSubscription(originalSubscription));
const unwatch = uniqueValueWatcher(getValidWatchSource(args), () => {
// checking if args are null to support useSubscriptionWithDependencies
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!subscriptionResponse.isSubscribed() || unref(argsWithDefault) === null) {
unwatch();
return;
}
subscriptionResponse.unsubscribe();
const newSubscription = manager.subscribe(action, argsWithDefault, options);
newSubscription.response.value ??= subscriptionResponse.response;
newSubscription.executed.value = newSubscription.executed.value || subscriptionResponse.executed;
Object.assign(subscriptionResponse, mapSubscription(newSubscription));
}, { deep: true });
const unwatchOptions = uniqueValueWatcher(getValidWatchSource(optionsArg), () => {
if (!subscriptionResponse.isSubscribed()) {
unwatchOptions();
return;
}
const options = unref(optionsArg);
const manager = options.manager ?? defaultSubscriptionManager;
const newSubscription = manager.subscribe(action, argsWithDefault, options);
subscriptionResponse.unsubscribe();
Object.assign(subscriptionResponse, mapSubscription(newSubscription));
}, { deep: true });
tryOnScopeDispose(() => {
const { lifecycle = 'component' } = unref(optionsArg);
if (lifecycle === 'component') {
subscriptionResponse.unsubscribe();
unwatchOptions();
unwatch();
}
});
return subscriptionResponse;
}
//# sourceMappingURL=useSubscription.js.map