( record: Record<string, unknown>, timestampCol: string, localState: ExistingRecordState | undefined, )
| 442 | } |
| 443 | |
| 444 | function shouldApplyRemoteRecord( |
| 445 | record: Record<string, unknown>, |
| 446 | timestampCol: string, |
| 447 | localState: ExistingRecordState | undefined, |
| 448 | ): boolean { |
| 449 | if (!localState) return true; |
| 450 | |
| 451 | const remoteTs = record[timestampCol] as number; |
| 452 | if (remoteTs > localState.timestamp) return true; |
| 453 | if (remoteTs < localState.timestamp) return false; |
| 454 | |
| 455 | // Preserved book deletes are represented as regular rows with deleted_at set. |
| 456 | // When timestamps tie, let the newer delete marker break the tie so devices |
| 457 | // cannot stay split between live and deleted copies of the same book. |
| 458 | if (!Object.prototype.hasOwnProperty.call(record, "deleted_at")) return false; |
| 459 | |
| 460 | const remoteDeletedAt = normalizeDeletedAt(record.deleted_at); |
| 461 | const localDeletedAt = localState.deletedAt ?? null; |
| 462 | if (remoteDeletedAt === undefined || remoteDeletedAt === localDeletedAt) return false; |
| 463 | |
| 464 | return (remoteDeletedAt ?? 0) > (localDeletedAt ?? 0); |
| 465 | } |
| 466 | |
| 467 | async function rememberRemoteTombstone( |
| 468 | db: Awaited<ReturnType<typeof getDB>>, |
no test coverage detected