import type { Appointment } from 'fhir/r4'; import { isRecordChanged } from './recordChanged'; import { isSaveRetired, isSaveTimedOut } from './saveOperation'; /** * Whether a failed write may still have landed: it was sent and no definite answer came back (no answer, out of * time after sending, or a server error). A refusal is an answer - nothing was saved - and so is a save retired * before it was sent. */ export const writeOutcomeUnknown = (error: unknown): boolean => { if (isRecordChanged(error) || isSaveRetired(error)) return false; if (isSaveTimedOut(error)) return error.mayHaveSaved; // An HttpError (by shape, so this stays free of the transport module): the server answered. const status = (error as { name?: unknown; status?: unknown } | null); if (status?.name === 'HttpError' && typeof status.status === 'number') return status.status >= 500; return true; }; export type SettledWrite = 'saved' | 'unknown'; /** * Settles a write whose answer never came by reading the Appointment as stored now: `landed` says whether that * record carries the change. A record without it is not proof the write failed, since the write may still be on * its way; that, like an unreadable record, leaves it unknown, and nothing is sent again until it is known. */ export const settleUnknownWrite = async ( read: () => Promise, landed: (stored: Appointment) => boolean, ): Promise => { try { return landed(await read()) ? 'saved' : 'unknown'; } catch (error) { if (isSaveRetired(error)) throw error; return 'unknown'; } };