feat(reader): separate Miliastra and track passes as cycles

Route source-classified activities into an independent Miliastra lane and
show dated battle passes once under Cycles. Genshin's About tab can disable
TCG tracking without deleting progress or history.

Activate routing and presentation together so no intermediate version moves
saved progress while still rendering its old owner. Preserve identities,
clock revisions and deletion timestamps across late writes and backups.
This commit is contained in:
Lucas Winther committed 2026-11-01 04:12:14 +01:00
1 parent 5576e5ad5c
commit b03a6ed2d1
31 files changed
+1127 -52

No files matched your search

+4 -3
View File
@@ -11,6 +11,7 @@ import {
type SaveResult,
} from "./schema.ts";
import { reduceReader, type ReaderAction } from "./reducer.ts";
import { routeReaderContent } from "./contentRouting.ts";
export interface ReaderStore {
getSnapshot(): ReaderState;
subscribe(listener: () => void): () => void;
@@ -58,10 +59,10 @@ export function initializeReader(
if (saved !== null) {
const parsed = ReaderStateSchema.safeParse(JSON.parse(saved));
if (!parsed.success) return { ok: false, reason: "invalid" };
const next = refreshAutomaticClocks(
const next = routeReaderContent(refreshAutomaticClocks(
reconcileLegacy(parsed.data, readLegacy(storage), at),
at,
);
));
if (next !== parsed.data) {
const result = tryWriteJson(storage, READER_KEYS.reader, next);
if (!result.ok) return result;
@@ -102,7 +103,7 @@ export function createReaderStore(
const apply = (action: ReaderAction): SaveResult => {
try {
const current = persisted() ?? state;
const next = reduceReader(current, action);
const next = routeReaderContent(reduceReader(current, action));
if (next === current) {
state = current;
notify();