type OptimisticRollbackOptions<T> = {
  save: () => Promise<void>;
  expected: T;
  getCurrent: () => T;
  rollback: () => void;
};

export async function saveWithOptimisticRollback<T>({
  save,
  expected,
  getCurrent,
  rollback,
}: OptimisticRollbackOptions<T>): Promise<void> {
  try {
    await save();
  } catch (error) {
    if (Object.is(getCurrent(), expected)) {
      rollback();
    }
    throw error;
  }
}

export function scheduleSaveWithOptimisticRollback<T>(
  options: OptimisticRollbackOptions<T>,
): void {
  void saveWithOptimisticRollback(options).catch(() => undefined);
}
