Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
b2eb05a1
Unverified
提交
b2eb05a1
authored
5月 09, 2025
作者:
Will Chen
提交者:
GitHub
5月 09, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Simplify error handling for IPC handlers (#119)
上级
c203b1d0
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
135 行增加
和
132 行删除
+135
-132
safe_handle.ts
src/ipc/handlers/safe_handle.ts
+24
-0
version_handlers.ts
src/ipc/handlers/version_handlers.ts
+111
-132
没有找到文件。
src/ipc/handlers/safe_handle.ts
0 → 100644
浏览文件 @
b2eb05a1
import
{
ipcMain
,
IpcMainInvokeEvent
}
from
"electron"
;
import
log
from
"electron-log"
;
export
function
createSafeHandler
(
logger
:
log
.
LogFunctions
)
{
return
(
channel
:
string
,
fn
:
(
event
:
IpcMainInvokeEvent
,
...
args
:
any
[])
=>
Promise
<
any
>
,
)
=>
{
ipcMain
.
handle
(
channel
,
async
(
event
:
IpcMainInvokeEvent
,
...
args
:
any
[])
=>
{
try
{
return
await
fn
(
event
,
...
args
);
}
catch
(
error
)
{
logger
.
error
(
`Error in
${
fn
.
name
}
: args:
${
JSON
.
stringify
(
args
)}
`
,
error
,
);
throw
new
Error
(
`[
${
channel
}
]
${
error
}
`
);
}
},
);
};
}
src/ipc/handlers/version_handlers.ts
浏览文件 @
b2eb05a1
import
{
ipcMain
}
from
"electron"
;
import
{
db
}
from
"../../db"
;
import
{
apps
,
messages
}
from
"../../db/schema"
;
import
{
desc
,
eq
,
and
,
gt
}
from
"drizzle-orm"
;
...
...
@@ -8,15 +7,17 @@ import path from "node:path";
import
{
getDyadAppPath
}
from
"../../paths/paths"
;
import
git
from
"isomorphic-git"
;
import
{
promises
as
fsPromises
}
from
"node:fs"
;
// Import our utility modules
import
{
withLock
}
from
"../utils/lock_utils"
;
import
{
getGitAuthor
}
from
"../utils/git_author"
;
import
log
from
"electron-log"
;
import
{
createSafeHandler
}
from
"./safe_handle"
;
const
logger
=
log
.
scope
(
"version_handlers"
);
const
handle
=
createSafeHandler
(
logger
);
export
function
registerVersionHandlers
()
{
ipcMain
.
handle
(
"list-versions"
,
async
(
_
,
{
appId
}:
{
appId
:
number
})
=>
{
handle
(
"list-versions"
,
async
(
_
,
{
appId
}:
{
appId
:
number
})
=>
{
const
app
=
await
db
.
query
.
apps
.
findFirst
({
where
:
eq
(
apps
.
id
,
appId
),
});
...
...
@@ -32,26 +33,21 @@ export function registerVersionHandlers() {
return
[];
}
try
{
const
commits
=
await
git
.
log
({
fs
,
dir
:
appPath
,
// KEEP UP TO DATE WITH ChatHeader.tsx
depth
:
10
_000
,
// Limit to last 10_000 commits for performance
});
const
commits
=
await
git
.
log
({
fs
,
dir
:
appPath
,
// KEEP UP TO DATE WITH ChatHeader.tsx
depth
:
10
_000
,
// Limit to last 10_000 commits for performance
});
return
commits
.
map
((
commit
)
=>
({
oid
:
commit
.
oid
,
message
:
commit
.
commit
.
message
,
timestamp
:
commit
.
commit
.
author
.
timestamp
,
}))
satisfies
Version
[];
}
catch
(
error
:
any
)
{
logger
.
error
(
`Error listing versions for app
${
appId
}
:`
,
error
);
throw
new
Error
(
`Failed to list versions:
${
error
.
message
}
`
);
}
return
commits
.
map
((
commit
)
=>
({
oid
:
commit
.
oid
,
message
:
commit
.
commit
.
message
,
timestamp
:
commit
.
commit
.
author
.
timestamp
,
}))
satisfies
Version
[];
});
ipcMain
.
handle
(
handle
(
"get-current-branch"
,
async
(
_
,
{
appId
}:
{
appId
:
number
}):
Promise
<
BranchResult
>
=>
{
const
app
=
await
db
.
query
.
apps
.
findFirst
({
...
...
@@ -86,7 +82,7 @@ export function registerVersionHandlers() {
},
);
ipcMain
.
handle
(
handle
(
"revert-version"
,
async
(
_
,
...
...
@@ -106,117 +102,109 @@ export function registerVersionHandlers() {
const
appPath
=
getDyadAppPath
(
app
.
path
);
try
{
await
git
.
checkout
({
fs
,
dir
:
appPath
,
ref
:
"main"
,
force
:
true
,
});
// Get status matrix comparing the target commit (previousVersionId as HEAD) with current working directory
const
matrix
=
await
git
.
statusMatrix
({
fs
,
dir
:
appPath
,
ref
:
previousVersionId
,
});
await
git
.
checkout
({
fs
,
dir
:
appPath
,
ref
:
"main"
,
force
:
true
,
});
// Get status matrix comparing the target commit (previousVersionId as HEAD) with current working directory
const
matrix
=
await
git
.
statusMatrix
({
fs
,
dir
:
appPath
,
ref
:
previousVersionId
,
});
// Process each file to revert to the state in previousVersionId
for
(
const
[
filepath
,
headStatus
,
workdirStatus
]
of
matrix
)
{
const
fullPath
=
path
.
join
(
appPath
,
filepath
);
// If file exists in HEAD (previous version)
if
(
headStatus
===
1
)
{
// If file doesn't exist or has changed in working directory, restore it from the target commit
if
(
workdirStatus
!==
1
)
{
const
{
blob
}
=
await
git
.
readBlob
({
fs
,
dir
:
appPath
,
oid
:
previousVersionId
,
filepath
,
});
await
fsPromises
.
mkdir
(
path
.
dirname
(
fullPath
),
{
recursive
:
true
,
});
await
fsPromises
.
writeFile
(
fullPath
,
Buffer
.
from
(
blob
));
}
// Process each file to revert to the state in previousVersionId
for
(
const
[
filepath
,
headStatus
,
workdirStatus
]
of
matrix
)
{
const
fullPath
=
path
.
join
(
appPath
,
filepath
);
// If file exists in HEAD (previous version)
if
(
headStatus
===
1
)
{
// If file doesn't exist or has changed in working directory, restore it from the target commit
if
(
workdirStatus
!==
1
)
{
const
{
blob
}
=
await
git
.
readBlob
({
fs
,
dir
:
appPath
,
oid
:
previousVersionId
,
filepath
,
});
await
fsPromises
.
mkdir
(
path
.
dirname
(
fullPath
),
{
recursive
:
true
,
});
await
fsPromises
.
writeFile
(
fullPath
,
Buffer
.
from
(
blob
));
}
// If file doesn't exist in HEAD but exists in working directory, delete it
else
if
(
headStatus
===
0
&&
workdirStatus
!==
0
)
{
if
(
fs
.
existsSync
(
fullPath
)
)
{
await
fsPromises
.
unlink
(
fullPath
);
await
git
.
remove
({
fs
,
dir
:
appPath
,
filepath
:
filep
ath
,
});
}
}
// If file doesn't exist in HEAD but exists in working directory, delete it
else
if
(
headStatus
===
0
&&
workdirStatus
!==
0
)
{
if
(
fs
.
existsSync
(
fullPath
))
{
await
fsPromises
.
unlink
(
fullPath
);
await
git
.
remove
({
fs
,
dir
:
appP
ath
,
filepath
:
filepath
,
}
);
}
}
}
// Stage all changes
await
git
.
add
({
fs
,
dir
:
appPath
,
filepath
:
"."
,
});
// Stage all changes
await
git
.
add
({
fs
,
dir
:
appPath
,
filepath
:
"."
,
});
// Create a revert commit
await
git
.
commit
({
fs
,
dir
:
appPath
,
message
:
`Reverted all changes back to version
${
previousVersionId
}
`
,
author
:
await
getGitAuthor
(),
});
// Create a revert commit
await
git
.
commit
({
fs
,
dir
:
appPath
,
message
:
`Reverted all changes back to version
${
previousVersionId
}
`
,
author
:
await
getGitAuthor
(),
});
// Find the chat and message associated with the commit hash
const
messageWithCommit
=
await
db
.
query
.
messages
.
findFirst
({
where
:
eq
(
messages
.
commitHash
,
previousVersionId
),
with
:
{
chat
:
true
,
},
// Find the chat and message associated with the commit hash
const
messageWithCommit
=
await
db
.
query
.
messages
.
findFirst
({
where
:
eq
(
messages
.
commitHash
,
previousVersionId
),
with
:
{
chat
:
true
,
},
});
// If we found a message with this commit hash, delete all subsequent messages (but keep this message)
if
(
messageWithCommit
)
{
const
chatId
=
messageWithCommit
.
chatId
;
// Find all messages in this chat with IDs > the one with our commit hash
const
messagesToDelete
=
await
db
.
query
.
messages
.
findMany
({
where
:
and
(
eq
(
messages
.
chatId
,
chatId
),
gt
(
messages
.
id
,
messageWithCommit
.
id
),
),
orderBy
:
desc
(
messages
.
id
),
});
// If we found a message with this commit hash, delete all subsequent messages (but keep this message)
if
(
messageWithCommit
)
{
const
chatId
=
messageWithCommit
.
chatId
;
// Find all messages in this chat with IDs > the one with our commit hash
const
messagesToDelete
=
await
db
.
query
.
messages
.
findMany
({
where
:
and
(
eq
(
messages
.
chatId
,
chatId
),
gt
(
messages
.
id
,
messageWithCommit
.
id
),
),
orderBy
:
desc
(
messages
.
id
),
});
logger
.
log
(
`Deleting
${
messagesToDelete
.
length
}
messages after commit
${
previousVersionId
}
from chat
${
chatId
}
`
,
);
// Delete the messages
if
(
messagesToDelete
.
length
>
0
)
{
await
db
.
delete
(
messages
)
.
where
(
and
(
eq
(
messages
.
chatId
,
chatId
),
gt
(
messages
.
id
,
messageWithCommit
.
id
),
),
);
}
}
}
catch
(
error
:
any
)
{
logger
.
error
(
`Error reverting to version
${
previousVersionId
}
for app
${
appId
}
:`
,
error
,
logger
.
log
(
`Deleting
${
messagesToDelete
.
length
}
messages after commit
${
previousVersionId
}
from chat
${
chatId
}
`
,
);
throw
new
Error
(
`Failed to revert version:
${
error
.
message
}
`
);
// Delete the messages
if
(
messagesToDelete
.
length
>
0
)
{
await
db
.
delete
(
messages
)
.
where
(
and
(
eq
(
messages
.
chatId
,
chatId
),
gt
(
messages
.
id
,
messageWithCommit
.
id
),
),
);
}
}
});
},
);
ipcMain
.
handle
(
handle
(
"checkout-version"
,
async
(
_
,
...
...
@@ -233,21 +221,12 @@ export function registerVersionHandlers() {
const
appPath
=
getDyadAppPath
(
app
.
path
);
try
{
// Checkout the target commit
await
git
.
checkout
({
fs
,
dir
:
appPath
,
ref
:
versionId
,
force
:
true
,
});
}
catch
(
error
:
any
)
{
logger
.
error
(
`Error checking out version
${
versionId
}
for app
${
appId
}
:`
,
error
,
);
throw
new
Error
(
`Failed to checkout version:
${
error
.
message
}
`
);
}
await
git
.
checkout
({
fs
,
dir
:
appPath
,
ref
:
versionId
,
force
:
true
,
});
});
},
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论