fix(chat): prevent guest quota reset on read failures

This commit is contained in:
2026-06-17 17:22:45 +08:00
parent afba85e809
commit a969030f40
4 changed files with 121 additions and 53 deletions
+24 -17
View File
@@ -19,20 +19,9 @@ import { Result, type Result as ResultT } from "@/utils/result";
export class SpAsyncUtil {
// ===== 私有静态状态 =====
// 环境判断 + lazy 初始化:SSR 用 memory driver,浏览器用 localStorage driver。
// 环境判断 + 安全初始化:SSR 用 memory driver,浏览器用 localStorage driver。
// unstorage 1.10+ 要求显式传入 localStorage,故这里同步注入 window.localStorage。
private static _storage: Storage = (() => {
if (typeof window === "undefined") {
// SSR 环境:无 window,降级为内存驱动
return createStorage({ driver: memoryDriver() });
}
// 浏览器环境:使用 localStorage 驱动
return createStorage({
driver: localStorageDriver({
base: "cozsweet:",
}),
});
})();
private static _storage: Storage = createDefaultStorage();
// 私有构造函数:禁止实例化(对齐 Dart `SpAsyncUtil._()`
private constructor() {}
@@ -170,11 +159,11 @@ export class SpAsyncUtil {
key: string,
schema: ZodType<T>,
): Promise<ResultT<T | null>> {
const r = await SpAsyncUtil.getString(key);
if (!r.success) return Result.err(r.error);
if (r.data === null) return Result.ok(null);
try {
const parsed = schema.parse(JSON.parse(r.data));
const value = await SpAsyncUtil._storage.getItem<unknown>(key);
if (value === null || value === undefined) return Result.ok(null);
const json = typeof value === "string" ? JSON.parse(value) : value;
const parsed = schema.parse(json);
return Result.ok(parsed);
} catch (e) {
return Result.err(toError(e));
@@ -230,3 +219,21 @@ export class SpAsyncUtil {
function toError(e: unknown): Error {
return e instanceof Error ? e : new Error(String(e));
}
function createDefaultStorage(): Storage {
if (typeof window === "undefined") {
return createStorage({ driver: memoryDriver() });
}
try {
return createStorage({
driver: localStorageDriver({
base: "cozsweet:",
localStorage: window.localStorage,
window,
}),
});
} catch {
return createStorage({ driver: memoryDriver() });
}
}