refactor(storage): use unstorage for session state

This commit is contained in:
2026-07-01 18:36:26 +08:00
parent 0251916a8a
commit ae6578923b
13 changed files with 398 additions and 246 deletions
+1
View File
@@ -10,5 +10,6 @@ export * from "./logger";
export * from "./platform-detect";
export * from "./pwa";
export * from "./result";
export * from "./session-storage";
export * from "./storage";
export * from "./url-launcher-util";
+87
View File
@@ -0,0 +1,87 @@
"use client";
import { createStorage, type Storage } from "unstorage";
import memoryDriver from "unstorage/drivers/memory";
import sessionStorageDriver from "unstorage/drivers/session-storage";
import type { ZodType } from "zod";
import { Result, type Result as ResultT } from "./result";
/**
* SessionAsyncUtil — 会话级键值存储工具类(基于 unstorage)。
*
* 与 `SpAsyncUtil` 的 localStorage 持久化定位不同,本工具只用于当前 tab
* 会话内的临时 UI 状态,例如跨路由返回时恢复滚动位置。
*/
export class SessionAsyncUtil {
private static _storage: Storage = createDefaultSessionStorage();
private constructor() {}
static setStorage(instance: Storage): void {
SessionAsyncUtil._storage = instance;
}
static getRawStorage(): Storage {
return SessionAsyncUtil._storage;
}
static async getJson<T>(
key: string,
schema: ZodType<T>,
): Promise<ResultT<T | null>> {
try {
const value = await SessionAsyncUtil._storage.getItem<unknown>(key);
if (value === null || value === undefined) return Result.ok(null);
const json = typeof value === "string" ? JSON.parse(value) : value;
return Result.ok(schema.parse(json));
} catch (e) {
return Result.err(toError(e));
}
}
static async setJson<T>(
key: string,
value: T,
schema?: ZodType<T>,
): Promise<ResultT<void>> {
try {
const validated = schema ? schema.parse(value) : value;
await SessionAsyncUtil._storage.setItem(key, JSON.stringify(validated));
return Result.ok(undefined);
} catch (e) {
return Result.err(toError(e));
}
}
static async remove(key: string): Promise<ResultT<void>> {
try {
await SessionAsyncUtil._storage.removeItem(key);
return Result.ok(undefined);
} catch (e) {
return Result.err(toError(e));
}
}
}
function toError(e: unknown): Error {
return e instanceof Error ? e : new Error(String(e));
}
function createDefaultSessionStorage(): Storage {
if (typeof window === "undefined") {
return createStorage({ driver: memoryDriver() });
}
try {
return createStorage({
driver: sessionStorageDriver({
base: "cozsweet:",
storage: window.sessionStorage,
window,
}),
});
} catch {
return createStorage({ driver: memoryDriver() });
}
}