Fix race condition in vim connect with ready signal

This commit is contained in:
Jared Miller 2026-01-27 16:17:33 -05:00
parent bbfc9998a5
commit 68a7517dec
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
3 changed files with 30 additions and 3 deletions

View file

@ -15,6 +15,9 @@ function send(msg: object) {
console.log(JSON.stringify(msg));
}
// signal to vim that bridge is ready
send({ type: "ready" });
function connect(roomName: string) {
doc = new Y.Doc();
text = doc.getText("content");

View file

@ -6,6 +6,7 @@ vim9script
var bridge_job: job
var bridge_channel: channel
var connected = false
var ready = false
var room = ""
var suppressing = false
@ -29,7 +30,9 @@ def OnOutput(ch: channel, msg: string)
return
endtry
if data.type == 'connected'
if data.type == 'ready'
ready = true
elseif data.type == 'connected'
connected = true
echom '[collab] connected to room: ' .. data.room
elseif data.type == 'disconnected'
@ -72,6 +75,7 @@ export def Connect(room_name: string)
endif
room = room_name
ready = false
bridge_job = job_start(['bun', 'run', bridge_script], {
mode: 'nl',
out_cb: OnOutput,
@ -79,8 +83,19 @@ export def Connect(room_name: string)
})
bridge_channel = job_getchannel(bridge_job)
# give it a moment to start
sleep 100m
# wait for bridge ready signal
var timeout = 50
while !ready && timeout > 0
sleep 10m
timeout -= 1
endwhile
if !ready
echoerr '[collab] bridge failed to start'
Disconnect()
return
endif
Send({type: 'connect', room: room_name})
# set up autocmds to send changes
@ -98,6 +113,7 @@ export def Disconnect()
bridge_channel = null
endif
connected = false
ready = false
room = ""
augroup CollabVim
autocmd!

View file

@ -12,6 +12,14 @@ export type ServerMessage =
| { type: "awareness"; data: number[] }
| { type: "peers"; count: number };
export type BridgeMessage =
| { type: "ready" }
| { type: "connected"; room: string }
| { type: "disconnected" }
| { type: "content"; text: string }
| { type: "peers"; count: number }
| { type: "error"; message: string };
export function encode(msg: ServerMessage): string {
return JSON.stringify(msg);
}