Resync initial event connections and render nested task blocks

This commit is contained in:
eezd committed 2026-10-20 18:59:54 +08:00
1 parent 2df1ab87df
commit f9cfb138ea
4 files changed
+52 -15

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
// @vitest-environment happy-dom
import { afterEach, expect, it, vi } from 'vitest'
import { connectEvents } from './events'
afterEach(() => { vi.useRealTimers(); vi.unstubAllGlobals() })
it('首次连接和重连均补同步,停止后不再连接', () => {
vi.useFakeTimers()
class Socket {
static CLOSED = 3
static instances: Socket[] = []
readyState = 0
onopen?: () => void
onclose?: () => void
close() { this.readyState = Socket.CLOSED }
constructor() { Socket.instances.push(this) }
}
vi.stubGlobal('WebSocket', Socket)
let synchronized = 0
const stop = connectEvents({ onEvents: () => {}, onResync: () => { synchronized++ } })
Socket.instances[0].onopen!()
expect(synchronized).toBe(1)
Socket.instances[0].onclose!()
vi.advanceTimersByTime(1000)
Socket.instances[1].onopen!()
expect(synchronized).toBe(2)
stop()
Socket.instances[1].onclose!()
vi.advanceTimersByTime(30000)
expect(Socket.instances).toHaveLength(2)
})
+3 -5
View File
@@ -1,4 +1,4 @@
// 订阅服务端的仓库变更事件;断线后指数退避重连,重连成功时触发全量同步
// 订阅服务端的仓库变更事件;断线后指数退避重连,每次连接成功时触发全量同步
export interface VaultEvent {
type: 'tree' | 'changed' | 'deleted' | 'moved' | 'settings' | 'plugins'
@@ -12,16 +12,14 @@ export function connectEvents(handlers: { onEvents: (evs: VaultEvent[]) => void;
let delay = 1000
let timer: ReturnType<typeof setTimeout> | undefined
let stopped = false
let connectedBefore = false
const connect = () => {
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'
ws = new WebSocket(`${proto}//${location.host}/api/v1/events`)
ws.onopen = () => {
delay = 1000
// 首次连接前的状态由初始化加载,之后每次重连都可能错过事件
if (connectedBefore) handlers.onResync()
connectedBefore = true
// 初始化读取到首次订阅之间也存在空窗,每次建立连接都补同步。
handlers.onResync()
}
ws.onmessage = (e) => handlers.onEvents(JSON.parse(e.data))
ws.onclose = () => {