33 lines
2.2 KiB
TypeScript
33 lines
2.2 KiB
TypeScript
"use client"
|
|
import { useEffect, useRef, useState } from "react"
|
|
import { backupRestoreCheckpointSchema, backupRestoreStorageKey, readBackupRestoreCheckpoint, type BackupRestoreCheckpoint } from "./backup-restore-checkpoint"
|
|
export function useBackupRestoreGuard(backendUrl: string, live: boolean) {
|
|
const [checkpoint, setCheckpoint] = useState<BackupRestoreCheckpoint | null>(null), current = useRef<BackupRestoreCheckpoint | null>(null)
|
|
const [hydrated, setHydrated] = useState(false), [error, setError] = useState<string | null>(null), blocked = useRef(false), alive = useRef(true)
|
|
const key = backupRestoreStorageKey(backendUrl)
|
|
useEffect(() => {
|
|
alive.current = true
|
|
queueMicrotask(() => {
|
|
if (!alive.current) return
|
|
try { const saved = live ? readBackupRestoreCheckpoint(sessionStorage.getItem(key)) : null; current.current = saved; setCheckpoint(saved) }
|
|
catch { blocked.current = true; setError("Не удалось прочитать отметку импорта. Проверьте состояние роутера перед новым восстановлением") }
|
|
setHydrated(true)
|
|
})
|
|
return () => { alive.current = false }
|
|
}, [key, live])
|
|
function begin(target: Omit<BackupRestoreCheckpoint, "requestedAt">) {
|
|
if (!live || !hydrated || !alive.current || blocked.current || current.current) return false
|
|
const value = backupRestoreCheckpointSchema.parse({ ...target, requestedAt: new Date().toISOString() })
|
|
try { sessionStorage.setItem(key, JSON.stringify(value)) }
|
|
catch { blocked.current = true; setError("Не удалось сохранить отметку импорта. Запрос не отправлен"); return false }
|
|
current.current = value; setCheckpoint(value); return true
|
|
}
|
|
function clear() {
|
|
if (!live || !hydrated || !alive.current) return false
|
|
try { sessionStorage.removeItem(key) }
|
|
catch { blocked.current = true; setError("Не удалось очистить отметку импорта. Новый импорт заблокирован"); return false }
|
|
current.current = null; blocked.current = false; setCheckpoint(null); setError(null); return true
|
|
}
|
|
return { checkpoint, hydrated, error, begin, clear, canStart: hydrated && !checkpoint && !error }
|
|
}
|