fix: 恢复成功后整体替换待写队列,修首屏自愈抢跑写空

This commit is contained in:
2026-11-02 23:30:30 +08:00
parent 62f5168dfe
commit ff1abee438
9 changed files with 101 additions and 43 deletions
+9 -5
View File
@@ -35,11 +35,14 @@ const RETRY_DELAYS = [0, 300, 700, 1200, 2000, 3000]
* - reachable: true, state: null → 宿主可达但还没有镜像(首次使用),可以写
* - reachable: false → 读不到,本次会话禁止写
*/
export async function loadHostState(): Promise<HostReadResult> {
export async function loadHostState(localAt = 0): Promise<HostReadResult> {
for (const delay of RETRY_DELAYS) {
if (delay) await new Promise((r) => setTimeout(r, delay))
try {
const r = await fetch(ENDPOINT, { cache: 'no-store', headers: { accept: 'application/json' } })
const r = await fetch(ENDPOINT + '?localAt=' + encodeURIComponent(String(localAt)), {
cache: 'no-store',
headers: { accept: 'application/json' },
})
if (!r.ok) continue
const j: any = await r.json()
if (j && typeof j === 'object' && j.state && typeof j.state === 'object') {
@@ -103,10 +106,11 @@ export function queueHostSave(patch: HostStateParts): void {
/**
* 宿主镜像已成功读到,放行写入。
* 传入读到的内容,让之后的半截写入也能带上另一半。
* 传入权威内容时**整体替换**待写队列 —— 首屏自愈等早于恢复发生的写入必须作废,
* 否则那半截空值会把刚恢复好的项目盖掉(真实事故)。
*/
export function markHydrated(seed?: HostStateParts): void {
if (seed) parts = { ...seed, ...parts }
export function markHydrated(authoritative?: HostStateParts | null): void {
parts = authoritative ? { projects: authoritative.projects, view: authoritative.view } : {}
hydrated = true
}