import axios from "axios"; import type { Metadata } from "../Metadata"; import { ResourceEventType } from "./ResourceEventType"; import { AdvancedWebSocket } from "./AdvancedWebSocket"; import { WebsocketSession } from "./WebsocketSession"; export interface HasMetadata { metadata: Metadata } export class ResourceEvent { constructor ( public type: ResourceEventType, public resources: T[] ) {} } export class ResourceRepo { private resources: Ref = ref(undefined); private websocket?: AdvancedWebSocket; static init() { return new ResourceRepo(); } listen(resource: string) { WebsocketSession.get((token: string) => { const webSocket = AdvancedWebSocket.open(StringUtils.format("%s/watch/%s/%s?token=%s", ApiConfig.getWsBase(), resource, this.getNamespace(), token), (event) => { const data = JSON.parse(event.data) as ResourceEvent; switch (data.type) { case ResourceEventType.INIT: { this.add(data.resources); break; } case ResourceEventType.ADDED: { this.add(data.resources); break; } case ResourceEventType.MODIFIED: { this.update(data.resources); break; } case ResourceEventType.DELETED: { this.delete(data.resources); break; } } }, () => { } ); this.websocket = webSocket; }); } private add(resources: T[]) { if (this.resources.value == null) { this.resources.value = []; } this.resources.value.push(...resources); } private delete(resources: T[]) { if (this.resources.value == null) { this.resources.value = []; } for (const resource of resources) { const index = this.resources.value.findIndex(item => item.metadata.uid === resource.metadata.uid); if (index != null) { this.resources.value.splice(index, 1); } } } private update(resources: T[]) { if (this.resources.value == null) { this.resources.value = []; } for (const resource of resources) { const index = this.resources.value.findIndex(item => item.metadata.uid === resource.metadata.uid); if (index != null) { this.resources.value[index] = resource; } } } load(resourceType: string) { this.refresh(resourceType); return this; } clear() { if (this.websocket) { this.websocket.close(); } } get() { return computed(() => { if (this.resources.value) { return this.resources.value.toSorted((a, b) => a.metadata.name.localeCompare(b.metadata.name)); } return undefined; }) } private refresh(resourceType: string) { const namespace = this.getNamespace(); let url = StringUtils.format("%s/resources/%s", ApiConfig.getHttpBase(), resourceType); if (namespace) { url = StringUtils.format("%s/%s", url, namespace); } axios.get(url) .then((response) => { this.resources.value = response.data; }); } private getNamespace() { return useRoute().params.namespace as string; } }