Initial commit

This commit is contained in:
root
2025-12-21 09:57:43 -05:00
committed by Sebastian Krupinski
commit db42b6699c
35 changed files with 6458 additions and 0 deletions

131
src/stores/servicesStore.ts Normal file
View File

@@ -0,0 +1,131 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { Ref, ComputedRef } from 'vue'
import type { ServiceInterface, ServiceRecord } from '../types/service'
import type { SourceSelector } from '../types/common'
import { serviceService } from '../services/serviceService'
import { ServiceObject } from '../models/service'
// Nested structure: provider -> service -> ServiceObject
type ServiceStore = Record<string, Record<string, ServiceObject>>
export const useServicesStore = defineStore('fileServices', () => {
const services: Ref<ServiceStore> = ref({})
const loading = ref(false)
const error: Ref<string | null> = ref(null)
const initialized = ref(false)
const serviceList: ComputedRef<ServiceObject[]> = computed(() => {
const result: ServiceObject[] = []
Object.values(services.value).forEach(providerServices => {
result.push(...Object.values(providerServices))
})
return result
})
const getService = (providerId: string, serviceId: string): ServiceObject | undefined => {
return services.value[providerId]?.[serviceId]
}
const hasService = (providerId: string, serviceId: string): boolean => {
return !!services.value[providerId]?.[serviceId]
}
const getProviderServices = (providerId: string): ServiceObject[] => {
return Object.values(services.value[providerId] || {})
}
const getRootId = (providerId: string, serviceId: string): string | undefined => {
return services.value[providerId]?.[serviceId]?.rootId
}
const setServices = (data: ServiceRecord) => {
const hydrated: ServiceStore = {}
for (const [id, serviceData] of Object.entries(data)) {
const providerId = serviceData.provider
if (!hydrated[providerId]) {
hydrated[providerId] = {}
}
hydrated[providerId][id] = new ServiceObject().fromJson(serviceData)
}
services.value = hydrated
initialized.value = true
}
const addService = (providerId: string, serviceId: string, service: ServiceInterface) => {
if (!services.value[providerId]) {
services.value[providerId] = {}
}
services.value[providerId][serviceId] = new ServiceObject().fromJson(service)
}
const removeService = (providerId: string, serviceId: string) => {
if (services.value[providerId]) {
delete services.value[providerId][serviceId]
}
}
const clearServices = () => {
services.value = {}
initialized.value = false
}
// API actions
const fetchServices = async (sources?: SourceSelector): Promise<void> => {
loading.value = true
error.value = null
try {
const data = await serviceService.list(sources)
setServices(data)
} catch (e) {
error.value = e instanceof Error ? e.message : 'Failed to fetch services'
throw e
} finally {
loading.value = false
}
}
const checkServiceExtant = async (sources: SourceSelector): Promise<Record<string, boolean>> => {
try {
return await serviceService.extant(sources)
} catch (e) {
error.value = e instanceof Error ? e.message : 'Failed to check services'
throw e
}
}
const fetchService = async (providerId: string, serviceId: string): Promise<ServiceObject> => {
try {
const data = await serviceService.fetch(providerId, serviceId)
addService(providerId, serviceId, data)
return services.value[providerId][serviceId]
} catch (e) {
error.value = e instanceof Error ? e.message : 'Failed to fetch service'
throw e
}
}
return {
// State
services,
loading,
error,
initialized,
// Computed
serviceList,
// Getters
getService,
hasService,
getProviderServices,
getRootId,
// Setters
setServices,
addService,
removeService,
clearServices,
// Actions
fetchServices,
checkServiceExtant,
fetchService,
}
})