88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
"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() });
|
|
}
|
|
}
|