68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
/** 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" };
|
|
}
|
|
}
|