fix: 同步应用循环数组解构错误(.for is not iterable)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// 多端同步引擎:全量差异对比 + 记录级新者胜 + 软删除墓碑
|
||||
// 实时性:本地变更 3 秒内推送;服务端变更通过 SSE 秒级通知其他端;60 秒轮询兜底
|
||||
import Dexie, { liveQuery } from 'dexie'
|
||||
import { db } from '../db/schema'
|
||||
import { getSetting, setSetting } from '../db/repo'
|
||||
import { getCloudCreds } from '../db/auth'
|
||||
@@ -167,6 +168,7 @@ let changeDebounce: number | null = null
|
||||
let sse: EventSource | null = null
|
||||
let sseKey = ''
|
||||
let realtimeAttached = false
|
||||
let realtimeSub: { unsubscribe: () => void } | null = null
|
||||
|
||||
export async function autoSyncNow(): Promise<void> {
|
||||
if (syncRunning) {
|
||||
@@ -179,20 +181,29 @@ export async function autoSyncNow(): Promise<void> {
|
||||
} catch { /* 自动同步静默失败,等待下次触发 */ }
|
||||
}
|
||||
|
||||
// 实时触发:本地任何数据变更 3 秒后自动推送
|
||||
// 实时触发:本地任何数据变更 3 秒后自动推送(Dexie 4 核心 liveQuery,跨全部业务表)
|
||||
export function enableRealtimeSync(): void {
|
||||
if (realtimeAttached) return
|
||||
realtimeAttached = true
|
||||
;(db as unknown as AnyRow).on('changes', () => {
|
||||
if (changesSuppressed || syncRunning) return
|
||||
if (changeDebounce) window.clearTimeout(changeDebounce)
|
||||
changeDebounce = window.setTimeout(() => { void autoSyncNow() }, 3000)
|
||||
const sub = liveQuery(async () => {
|
||||
const counts: Record<string, number> = {}
|
||||
for (const t of TABLES) counts[t] = await db.table(t).count()
|
||||
return counts
|
||||
})
|
||||
realtimeSub = sub.subscribe({
|
||||
next: () => {
|
||||
if (changesSuppressed || syncRunning) return
|
||||
if (changeDebounce) globalThis.clearTimeout(changeDebounce)
|
||||
changeDebounce = globalThis.setTimeout(() => { void autoSyncNow() }, 3000)
|
||||
},
|
||||
error: () => { /* 忽略监听错误,轮询兜底 */ }
|
||||
})
|
||||
}
|
||||
|
||||
export function stopRealtime(): void {
|
||||
if (realtimeSub) { realtimeSub.unsubscribe(); realtimeSub = null }
|
||||
if (sse) { sse.close(); sse = null; sseKey = '' }
|
||||
if (changeDebounce) { window.clearTimeout(changeDebounce); changeDebounce = null }
|
||||
if (changeDebounce) { globalThis.clearTimeout(changeDebounce); changeDebounce = null }
|
||||
}
|
||||
|
||||
// 服务端 SSE 通知:其他端有变更时立即拉取
|
||||
@@ -220,7 +231,7 @@ export async function runSync(config: SyncConfig): Promise<SyncResult> {
|
||||
const result = await doRunSync(config)
|
||||
if (pendingSync) {
|
||||
pendingSync = false
|
||||
window.setTimeout(() => { void autoSyncNow() }, 800)
|
||||
globalThis.setTimeout(() => { void autoSyncNow() }, 800)
|
||||
}
|
||||
return result
|
||||
} finally {
|
||||
@@ -308,9 +319,9 @@ async function doRunSync(config: SyncConfig): Promise<SyncResult> {
|
||||
removed++
|
||||
}
|
||||
}
|
||||
for (const [u, srow] of serverRows) {
|
||||
if (dead.has(u)) continue
|
||||
const local = byUuid.get(u)
|
||||
for (const srow of serverRows) {
|
||||
if (dead.has(srow.uuid)) continue
|
||||
const local = byUuid.get(srow.uuid)
|
||||
if (!local) {
|
||||
await table.add({ ...srow })
|
||||
pulled++
|
||||
|
||||
Reference in New Issue
Block a user