Release v0.1.8 2026-07-13
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createHunterSave } from "./data";
|
||||
import { resolveSaveContinuation, saveVersionsMatch } from "./saveContinuation";
|
||||
|
||||
function save(updatedAt: string) {
|
||||
return createHunterSave(1, updatedAt, "Test Hunter");
|
||||
}
|
||||
|
||||
describe("save continuation", () => {
|
||||
it("creates only when neither copy exists", () => {
|
||||
expect(resolveSaveContinuation({ local: null, online: null })).toBe("create");
|
||||
});
|
||||
|
||||
it("uses whichever single copy exists", () => {
|
||||
const local = save("2026-07-13T12:00:00.000Z");
|
||||
const online = save("2026-07-13T13:00:00.000Z");
|
||||
expect(resolveSaveContinuation({ local, online: null })).toBe("local");
|
||||
expect(resolveSaveContinuation({ local: null, online })).toBe("online");
|
||||
});
|
||||
|
||||
it("asks only when online copy is newer", () => {
|
||||
const local = save("2026-07-13T12:00:00.000Z");
|
||||
expect(resolveSaveContinuation({ local, online: save("2026-07-13T13:00:00.000Z") })).toBe("choose");
|
||||
expect(resolveSaveContinuation({ local, online: save("2026-07-13T11:00:00.000Z") })).toBe("local");
|
||||
expect(resolveSaveContinuation({ local, online: save(local.updatedAt) })).toBe("local");
|
||||
});
|
||||
|
||||
it("matches downloaded copies by slot and timestamp", () => {
|
||||
const local = save("2026-07-13T12:00:00.000Z");
|
||||
expect(saveVersionsMatch(local, save(local.updatedAt))).toBe(true);
|
||||
expect(saveVersionsMatch(local, save("2026-07-13T13:00:00.000Z"))).toBe(false);
|
||||
expect(saveVersionsMatch(local, null)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { HunterSave, SaveSlotState } from "./types";
|
||||
|
||||
export type SaveContinuation = "create" | "local" | "online" | "choose";
|
||||
|
||||
function saveTimestamp(save: HunterSave): number | null {
|
||||
const timestamp = Date.parse(save.updatedAt);
|
||||
return Number.isFinite(timestamp) ? timestamp : null;
|
||||
}
|
||||
|
||||
export function resolveSaveContinuation(slot: Pick<SaveSlotState, "local" | "online">): SaveContinuation {
|
||||
if (!slot.local) return slot.online ? "online" : "create";
|
||||
if (!slot.online) return "local";
|
||||
|
||||
const localTimestamp = saveTimestamp(slot.local);
|
||||
const onlineTimestamp = saveTimestamp(slot.online);
|
||||
if (localTimestamp !== null && onlineTimestamp !== null && onlineTimestamp > localTimestamp) return "choose";
|
||||
return "local";
|
||||
}
|
||||
|
||||
export function saveVersionsMatch(local: HunterSave | null, online: HunterSave | null): boolean {
|
||||
return Boolean(local && online && local.slotId === online.slotId && local.updatedAt === online.updatedAt);
|
||||
}
|
||||
Reference in New Issue
Block a user