/** * Providers Store */ import { ref, computed, readonly } from 'vue' import { defineStore } from 'pinia' import { providerService } from '../services' import { ProviderObject } from '../models/provider' import type { SourceSelector } from '../types' export const useProvidersStore = defineStore('peopleProvidersStore', () => { // State const _providers = ref>({}) const transceiving = ref(false) /** * Get count of providers in store */ const count = computed(() => Object.keys(_providers.value).length) /** * Check if any providers are present in store */ const has = computed(() => count.value > 0) /** * Get all providers present in store */ const providers = computed(() => Object.values(_providers.value)) /** * Get a specific provider from store, with optional retrieval * * @param identifier - Provider identifier * @param retrieve - Retrieve behavior: true = fetch if missing or refresh, false = cache only * * @returns Provider object or null */ function provider(identifier: string, retrieve: boolean = false): ProviderObject | null { if (retrieve === true && !_providers.value[identifier]) { console.debug(`[People Manager][Store] - Force fetching provider "${identifier}"`) fetch(identifier) } return _providers.value[identifier] || null } // Actions /** * Retrieve all or specific providers, optionally filtered by source selector * * @param request - list request parameters * * @returns Promise with provider object list keyed by provider identifier */ async function list(sources?: SourceSelector): Promise> { transceiving.value = true try { const providers = await providerService.list({ sources }) // Merge retrieved providers into state _providers.value = { ..._providers.value, ...providers } console.debug('[People Manager][Store] - Successfully retrieved', Object.keys(providers).length, 'providers') return providers } catch (error: any) { console.error('[People Manager][Store] - Failed to retrieve providers:', error) throw error } finally { transceiving.value = false } } /** * Retrieve a specific provider by identifier * * @param identifier - provider identifier * * @returns Promise with provider object */ async function fetch(identifier: string): Promise { transceiving.value = true try { const provider = await providerService.fetch({ identifier }) // Merge fetched provider into state _providers.value[provider.identifier] = provider console.debug('[People Manager][Store] - Successfully fetched provider:', provider.identifier) return provider } catch (error: any) { console.error('[People Manager][Store] - Failed to fetch provider:', error) throw error } finally { transceiving.value = false } } /** * Retrieve provider availability status for a given source selector * * @param sources - source selector to check availability for * * @returns Promise with provider availability status */ async function extant(sources: SourceSelector) { transceiving.value = true try { const response = await providerService.extant({ sources }) Object.entries(response).forEach(([providerId, providerStatus]) => { if (providerStatus === false) { delete _providers.value[providerId] } }) console.debug('[People Manager][Store] - Successfully checked', sources ? Object.keys(sources).length : 0, 'providers') return response } catch (error: any) { console.error('[People Manager][Store] - Failed to check providers:', error) throw error } finally { transceiving.value = false } } // Return public API return { // State transceiving: readonly(transceiving), // computed count, has, providers, provider, // functions list, fetch, extant, } })