fix(store): fix structuredClone

This commit is contained in:
2026-02-28 16:31:50 +08:00
parent b3da1222d9
commit 717b7237a2

View File

@@ -145,6 +145,56 @@ const initialLabelState = {
}, },
} }
const deepCloneFallback = <T>(value: T, cache = new WeakMap()): T => {
if (value === null || typeof value !== "object") return value
if (cache.has(value as object)) return cache.get(value as object)
if (value instanceof Date) return new Date(value.getTime()) as T
if (value instanceof Map) {
const clonedMap = new Map()
cache.set(value as object, clonedMap)
value.forEach((mapValue, mapKey) => {
clonedMap.set(
deepCloneFallback(mapKey, cache),
deepCloneFallback(mapValue, cache)
)
})
return clonedMap as T
}
if (value instanceof Set) {
const clonedSet = new Set()
cache.set(value as object, clonedSet)
value.forEach((setValue) => {
clonedSet.add(deepCloneFallback(setValue, cache))
})
return clonedSet as T
}
if (Array.isArray(value)) {
const clonedArr: any[] = []
cache.set(value as object, clonedArr)
value.forEach((item, index) => {
clonedArr[index] = deepCloneFallback(item, cache)
})
return clonedArr as T
}
const clonedObj: Record<string, any> = {}
cache.set(value as object, clonedObj)
Object.keys(value as object).forEach((key) => {
clonedObj[key] = deepCloneFallback((value as any)[key], cache)
})
return clonedObj as T
}
const safeClone = <T>(value: T): T => {
try {
return structuredClone(value)
} catch (error) {
console.warn("structuredClone failed, fallback to deep clone", error)
return deepCloneFallback(value)
}
}
export const initialDetail = { export const initialDetail = {
comment: [], comment: [],
create_timestamp: 0, create_timestamp: 0,
@@ -301,8 +351,8 @@ export const useLabelStore = create(
labelData.get(imageId)?.set(operationId, [path]) labelData.get(imageId)?.set(operationId, [path])
} }
console.log("绘制时", labelData) console.log("绘制时", labelData)
useLabelStore.getState().pushStateStack(structuredClone(labelData)) useLabelStore.getState().pushStateStack(safeClone(labelData))
return { ...state, label: structuredClone(labelData) } return { ...state, label: safeClone(labelData) }
}), }),
// 删除path // 删除path