import type { Appointment } from 'fhir/r4'; import { onViewerChange, viewerEpoch, writeThroughViewer } from './writeThroughHold'; // Records of a visit this viewer already knows (a row's Encounter, or one a Prepare named), sent with every Prepare and save // so the server reads each by id; kept per viewer, patient and visit while the page is open, never trimmed. export const KNOWN_ENCOUNTERS_HEADER = 'X-Visit-Known-Encounters'; export interface VisitScope { patientId?: string; appointmentId?: string; } const known = new Map(); onViewerChange(() => known.clear()); const keyOf = ({ patientId, appointmentId }: VisitScope): string | undefined => patientId && appointmentId ? [viewerEpoch(), writeThroughViewer() ?? '', patientId, appointmentId].join('|') : undefined; export const rememberVisitRecords = (scope: VisitScope, ids: (string | undefined)[]): void => { const key = keyOf(scope); if (!key) return; const list = known.get(key) ?? []; for (const id of ids) if (id && !list.includes(id)) list.push(id); if (list.length > 0) known.set(key, list); }; export const knownVisitRecords = (scope: VisitScope): string[] => { const key = keyOf(scope); return key ? [...(known.get(key) ?? [])] : []; }; /** The visit an Appointment save is for, as the known records are kept. */ export const visitScopeOf = (appointment: Appointment): VisitScope => ({ appointmentId: appointment.id, patientId: appointment.participant?.find((p) => p.actor?.reference?.startsWith('Patient/'))?.actor?.reference?.slice('Patient/'.length), }); /** The header a save of this visit carries, when its viewer knows of any of its records. */ export const knownVisitRecordsHeader = (scope: VisitScope): Record => { const ids = knownVisitRecords(scope); return ids.length > 0 ? { [KNOWN_ENCOUNTERS_HEADER]: ids.join(',') } : {}; };