Skip to content

Commit 0457708

Browse files
authored
fix: change handle_sse and handle_json to properly parse streaming vim.fn.jobstart on_stdout calls (#89)
#66 #85 #88
1 parent 81ac51f commit 0457708

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

lua/opencode/cli/client.lua

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ local sse_state = {
1313
}
1414

1515
---@param data table
16-
---@return table|nil
16+
---@return table
1717
local function handle_sse(data)
18+
local responses = {}
19+
1820
for _, line in ipairs(data) do
1921
if line ~= "" then
2022
local clean_line = (line:gsub("^data: ?", ""))
@@ -26,28 +28,38 @@ local function handle_sse(data)
2628

2729
local ok, response = pcall(vim.fn.json_decode, full_event)
2830
if ok then
29-
return response
31+
table.insert(responses, response)
3032
else
3133
vim.notify("SSE JSON decode error: " .. full_event, vim.log.levels.ERROR, { title = "opencode" })
3234
end
3335
end
3436
end
37+
38+
return responses
3539
end
3640

41+
local json_state = {
42+
buffer = {},
43+
}
44+
3745
---@param data table
38-
---@return table|nil
46+
---@return table
3947
local function handle_json(data)
40-
for _, line in ipairs(data) do
41-
if line == "" then
42-
return
43-
end
44-
local ok, response = pcall(vim.fn.json_decode, line)
48+
if #data == 1 and data[1] == "" then -- this is eof
49+
local full_data = table.concat(json_state.buffer)
50+
json_state.buffer = {}
51+
52+
local ok, response = pcall(vim.fn.json_decode, full_data)
4553
if ok then
46-
return response
54+
return { response }
4755
else
48-
vim.notify("JSON decode error: " .. line, vim.log.levels.ERROR, { title = "opencode" })
56+
vim.notify("JSON decode error: " .. full_data, vim.log.levels.ERROR, { title = "opencode" })
4957
end
58+
else
59+
vim.list_extend(json_state.buffer, data)
5060
end
61+
62+
return {}
5163
end
5264

5365
---@param url string
@@ -77,14 +89,16 @@ local function curl(url, method, body, callback, is_sse)
7789
local stderr_lines = {}
7890
return vim.fn.jobstart(command, {
7991
on_stdout = function(_, data)
80-
local response
92+
local responses
8193
if is_sse then
82-
response = handle_sse(data)
94+
responses = handle_sse(data)
8395
else
84-
response = handle_json(data)
96+
responses = handle_json(data)
8597
end
86-
if response and callback then
87-
callback(response)
98+
if callback then
99+
for _, response in ipairs(responses) do
100+
callback(response)
101+
end
88102
end
89103
end,
90104
on_stderr = function(_, data)

0 commit comments

Comments
 (0)