refactor(storage): use unstorage for session state
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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() });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user