feat(store): add snapshot() and atomic json write
Problem: the single-level undo used shallow references so mutations during diff.apply() corrupted the saved state. JSON writes were also non-atomic, risking partial writes on crash. Solution: add M.snapshot() which deep-copies active tasks (including _extra). Change M.save() to write a .tmp file then rename atomically.
This commit is contained in:
parent
fc45ca3fcd
commit
4e9ce2bc8a
1 changed files with 29 additions and 2 deletions
|
|
@ -175,12 +175,18 @@ function M.save()
|
||||||
table.insert(out.tasks, task_to_table(task))
|
table.insert(out.tasks, task_to_table(task))
|
||||||
end
|
end
|
||||||
local encoded = vim.json.encode(out)
|
local encoded = vim.json.encode(out)
|
||||||
local f = io.open(path, 'w')
|
local tmp = path .. '.tmp'
|
||||||
|
local f = io.open(tmp, 'w')
|
||||||
if not f then
|
if not f then
|
||||||
error('pending.nvim: cannot write to ' .. path)
|
error('pending.nvim: cannot write to ' .. tmp)
|
||||||
end
|
end
|
||||||
f:write(encoded)
|
f:write(encoded)
|
||||||
f:close()
|
f:close()
|
||||||
|
local ok, rename_err = os.rename(tmp, path)
|
||||||
|
if not ok then
|
||||||
|
os.remove(tmp)
|
||||||
|
error('pending.nvim: cannot rename ' .. tmp .. ' to ' .. path .. ': ' .. tostring(rename_err))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return pending.Data
|
---@return pending.Data
|
||||||
|
|
@ -284,6 +290,27 @@ function M.replace_tasks(tasks)
|
||||||
M.data().tasks = tasks
|
M.data().tasks = tasks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return pending.Task[]
|
||||||
|
function M.snapshot()
|
||||||
|
local result = {}
|
||||||
|
for _, task in ipairs(M.active_tasks()) do
|
||||||
|
local copy = {}
|
||||||
|
for k, v in pairs(task) do
|
||||||
|
if k ~= '_extra' then
|
||||||
|
copy[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if task._extra then
|
||||||
|
copy._extra = {}
|
||||||
|
for k, v in pairs(task._extra) do
|
||||||
|
copy._extra[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(result, copy --[[@as pending.Task]])
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
---@param id integer
|
---@param id integer
|
||||||
function M.set_next_id(id)
|
function M.set_next_id(id)
|
||||||
M.data().next_id = id
|
M.data().next_id = id
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue