import type { AnyFunction } from '@robonen/stdlib'; import { effectScope } from 'vue'; // TODO: maybe we should control subscriptions and dispose them when the child scope is disposed /** * @name useAppSharedState * @category State * @description Provides a shared state object for use across Vue instances * * @param {Function} stateFactory A factory function that returns the shared state object * @returns {Function} A function that returns the shared state object * * @example * const useSharedState = useAppSharedState((initValue?: number) => { * const count = ref(initValue ?? 0); * return { count }; * }); * * @example * const useSharedState = useAppSharedState(() => { * const state = reactive({ count: 0 }); * const increment = () => state.count++; * return { state, increment }; * }); * * @since 0.0.1 */ export function useAppSharedState(stateFactory: Fn) { let initialized = false; let state: ReturnType; const scope = effectScope(true); return ((...args: Parameters) => { if (!initialized) { state = scope.run(() => stateFactory(...args)); initialized = true; } return state; }); }