import { useEffect } from 'react'; import { ImmunizationRecommendation } from 'fhir/r4'; import { useImmunizationRecommendationServiceContext, useFhirServiceContext, usePatientServiceContext, useWebSocketServiceContext } from '../services'; import { isArchived } from '../utils/archivedResource'; export const useFhirImmunizationRecommendationBroadcast = () => { const { subscribe, unsubscribe } = useWebSocketServiceContext(); const { immunizationRecommendationsList, setImmunizationRecommendationsList } = useImmunizationRecommendationServiceContext(); const { patientState } = usePatientServiceContext(); const { extractReferenceId } = useFhirServiceContext(); useEffect(() => { if (!patientState) { return; } const handleImmunizationRecommendationEvent = (cloudEvent: any) => { const immunizationRecommendation: ImmunizationRecommendation = cloudEvent.data; const eventType = cloudEvent.type; const patientId = extractReferenceId(immunizationRecommendation.patient); if (patientState.id === patientId) { switch (eventType) { case 'com.akashichealthrecords.fhir.immunizationrecommendation.created': // The list has two writers: this broadcast, and the service's own refetch after a write // (several of which POLL until the new id appears). Refetch first and the list already holds // the record, so an unconditional append put a SECOND copy of it on screen - observed on a // patient's questionnaire answers, where one submission rendered as two completed forms. // Keeping the broadcast's copy rather than skipping: its body is at least as fresh. setImmunizationRecommendationsList(prev => prev.some(p => p.id === immunizationRecommendation.id) ? prev.map(p => p.id === immunizationRecommendation.id ? immunizationRecommendation : p) : [...prev, immunizationRecommendation] ); break; case 'com.akashichealthrecords.fhir.immunizationrecommendation.updated': setImmunizationRecommendationsList(prev => isArchived(immunizationRecommendation) ? prev.filter(p => p.id !== immunizationRecommendation.id) : prev.map(p => p.id === immunizationRecommendation.id ? immunizationRecommendation : p) ); break; case 'com.akashichealthrecords.fhir.immunizationrecommendation.deleted': setImmunizationRecommendationsList(prev => prev.filter(p => p.id !== immunizationRecommendation.id)); break; } } }; subscribe('com.akashichealthrecords.fhir.immunizationrecommendation.created', handleImmunizationRecommendationEvent); subscribe('com.akashichealthrecords.fhir.immunizationrecommendation.updated', handleImmunizationRecommendationEvent); subscribe('com.akashichealthrecords.fhir.immunizationrecommendation.deleted', handleImmunizationRecommendationEvent); return () => { unsubscribe('com.akashichealthrecords.fhir.immunizationrecommendation.created', handleImmunizationRecommendationEvent); unsubscribe('com.akashichealthrecords.fhir.immunizationrecommendation.updated', handleImmunizationRecommendationEvent); unsubscribe('com.akashichealthrecords.fhir.immunizationrecommendation.deleted', handleImmunizationRecommendationEvent); }; }, [patientState, subscribe, unsubscribe, extractReferenceId, immunizationRecommendationsList]); };