1
0

feat: add playable actors and seamless journey state

This commit is contained in:
2026-08-11 19:10:14 -07:00
parent 4e313c4a79
commit a2a52bfdae
19 changed files with 2778 additions and 24 deletions
+67
View File
@@ -0,0 +1,67 @@
/** Failure-contained session persistence with no dependency on browser globals. */
import { decodeJourneySnapshot, encodeJourneySnapshot } from "./state.ts";
import type {
JourneySessionClearResult,
JourneySessionLoadResult,
JourneySessionSaveResult,
JourneyState,
JourneyStorageAdapter,
} from "./types.ts";
function validKey(key: string): boolean {
return typeof key === "string" && key.trim().length > 0;
}
export function saveJourneySession(
storage: JourneyStorageAdapter,
key: string,
state: JourneyState,
): JourneySessionSaveResult {
if (!validKey(key)) return { ok: false, error: "journey: session key is empty" };
let encoded: string;
try {
encoded = encodeJourneySnapshot(state);
} catch (error) {
return {
ok: false,
error: error instanceof Error ? error.message : "journey: snapshot encoding failed",
};
}
try {
storage.setItem(key, encoded);
return { ok: true };
} catch {
return { ok: false, error: "journey: session storage is unavailable" };
}
}
export function loadJourneySession(
storage: JourneyStorageAdapter,
key: string,
): JourneySessionLoadResult {
if (!validKey(key)) return { status: "invalid", error: "journey: session key is empty" };
let encoded: string | null;
try {
encoded = storage.getItem(key);
} catch {
return { status: "unavailable", error: "journey: session storage is unavailable" };
}
if (encoded === null) return { status: "missing" };
const decoded = decodeJourneySnapshot(encoded);
if (!decoded.ok) return { status: "invalid", error: decoded.error };
return { status: "loaded", state: decoded.state };
}
export function clearJourneySession(
storage: JourneyStorageAdapter,
key: string,
): JourneySessionClearResult {
if (!validKey(key)) return { ok: false, error: "journey: session key is empty" };
try {
storage.removeItem(key);
return { ok: true };
} catch {
return { ok: false, error: "journey: session storage is unavailable" };
}
}