fix(persistence): harden coerceEpoch null guard + autosave catch rollback

- coerceEpoch: early-return fallback on null/undefined input (was falling
  through to new Date(null) → epoch 0, surfacing as 1970-01-01 in the
  stories list); also unify the tail branch to Number.isFinite for
  consistency with the number-type fast path
- autosave .catch: roll back lastSavedFingerprintRef on unexpected throw
  so the next session change retries instead of silently marking the
  content as saved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yuanzonghao
2026-06-27 18:36:26 +08:00
parent da74e3e763
commit cf6e08aec4
2 changed files with 7 additions and 5 deletions
+2 -1
View File
@@ -19,12 +19,13 @@ export const STORY_SCHEMA_VERSION = 1;
* crosses a storage/serialization boundary and could arrive as a non-number,
* guarding against the historical `t.getTime is not a function` white-screen. */
export function coerceEpoch(value: unknown, fallback: number): number {
if (value == null) return fallback;
// Number.isFinite (not just !isNaN) so ±Infinity also falls through to the
// fallback — new Date(Infinity).getTime() is NaN, not a usable epoch.
if (typeof value === "number" && Number.isFinite(value)) return value;
const d = value instanceof Date ? value : new Date(value as string | number);
const t = d.getTime();
return Number.isNaN(t) ? fallback : t;
return Number.isFinite(t) ? t : fallback;
}
/** local-first sync state of a record.