Skip to content

Commit 9556769

Browse files
cyfung1031CodFrmCopilot
authored
🐛 修正 FileSystemObserver 未能持续监听问题 (#1160)
* 修正 FileSystemObserver 未能持续监听问题 * 发生 NotFoundError 等错误时,重置 Watch File * Update src/pkg/utils/file-tracker.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update file-tracker.ts * Update file-tracker.ts * Update file-tracker.ts --------- Co-authored-by: wangyizhi <i@xloli.top> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1c44b68 commit 9556769

2 files changed

Lines changed: 56 additions & 15 deletions

File tree

src/pages/install/App.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ function App() {
442442
}
443443
}
444444

445+
async function onWatchFileError() {
446+
// e.g. NotFoundError
447+
setWatchFile(false);
448+
}
449+
445450
const memoWatchFile = useMemo(() => {
446451
return `${watchFile}.${scriptInfo?.uuid}.${localFileHandle?.name}`;
447452
}, [watchFile, scriptInfo, localFileHandle]);
@@ -458,6 +463,7 @@ function App() {
458463
uuid,
459464
fileName,
460465
setCode: onWatchFileCodeChanged,
466+
onFileError: onWatchFileError,
461467
};
462468
// 进行监听
463469
startFileTrack(handle, ftInfo);

src/pkg/utils/file-tracker.ts

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,64 @@ export type FTInfo = {
55
fileName: string;
66
setCode(code: string, hideInfo?: boolean): void;
77
lastModified?: number;
8+
onFileError(): void;
9+
};
10+
11+
const getHandleRecord = async (root: FileSystemFileHandle, observer: FileSystemObserverInstance) => {
12+
for (const [fileHandle, ftInfo, fileObserver] of handleRecords) {
13+
if (fileObserver !== observer) continue;
14+
try {
15+
const isSame = await root.isSameEntry(fileHandle);
16+
if (isSame) {
17+
return ftInfo;
18+
}
19+
} catch (e) {
20+
// 捕捉非预期错误
21+
console.warn(e);
22+
}
23+
}
24+
return null;
825
};
926

1027
const callback = async (records: FileSystemChangeRecord[], observer: FileSystemObserverInstance) => {
11-
for (const record of records) {
12-
const { root, type } = record;
13-
if (!(root instanceof FileSystemFileHandle) || type !== "modified") continue;
14-
for (const [fileHandle, ftInfo, fileObserver] of handleRecords) {
15-
if (fileObserver !== observer) continue;
28+
try {
29+
for (const record of records) {
30+
const { root, type } = record;
31+
if (!(root instanceof FileSystemFileHandle)) continue;
32+
// 只要 FileSystemObserver 侦测到档案改变,就试一下找记录和读档
33+
const ftInfo = await getHandleRecord(root, observer);
34+
// 如没有记录则忽略
35+
if (!ftInfo) continue;
36+
let file: File | null = null;
1637
try {
17-
const isSame = await root.isSameEntry(fileHandle);
18-
if (!isSame) continue;
19-
// 调用安装
20-
const file = await root.getFile();
21-
// 避免重复更新
22-
if (ftInfo.lastModified === file.lastModified) continue;
23-
ftInfo.lastModified = file.lastModified;
24-
const code = await file.text();
25-
if (code && typeof code === "string") {
26-
ftInfo.setCode(code, false);
38+
const fRead = await root.getFile();
39+
if (fRead && fRead.lastModified > 0 && fRead.size > 0) {
40+
// 有档案内容读取权限,排除空档案
41+
file = fRead;
2742
}
2843
} catch (e) {
44+
// 档案改名或删掉时,或会被此捕捉(预期报错)
2945
console.warn(e);
46+
unmountFileTrack(root);
47+
ftInfo.onFileError();
48+
}
49+
// 如读档失败则忽略
50+
if (!file) continue;
51+
// 如成功读档但显示为失败,则重新 observe
52+
if (type === "errored") {
53+
observer.observe(root);
54+
}
55+
// 以 lastModified 判断避免重复更新
56+
if (ftInfo.lastModified === file.lastModified) continue;
57+
ftInfo.lastModified = file.lastModified;
58+
const code = await file.text();
59+
if (code && typeof code === "string") {
60+
ftInfo.setCode(code, false);
3061
}
3162
}
63+
} catch (e) {
64+
// 捕捉非预期错误
65+
console.warn(e);
3266
}
3367
};
3468

@@ -49,6 +83,7 @@ export const unmountFileTrack = async (fileHandle: FileSystemFileHandle) => {
4983
}
5084
}
5185
} catch (e) {
86+
// 捕捉非预期错误
5287
console.warn(e);
5388
}
5489
return false;

0 commit comments

Comments
 (0)