Skip to content

Commit c2caeab

Browse files
mbostockprichey
andauthored
re-initialize watchers on rename (#67)
* Handle rename event * re-initialize watchers on rename * handle rename, take two --------- Co-authored-by: Preston Richey <[email protected]>
1 parent 7da86ff commit c2caeab

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

src/preview.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {WatchEventType} from "node:fs";
1+
import type {WatchListener} from "node:fs";
22
import {watch, type FSWatcher} from "node:fs";
33
import {access, constants, readFile, stat} from "node:fs/promises";
44
import {createServer, type IncomingMessage, type RequestListener} from "node:http";
@@ -135,22 +135,38 @@ function handleWatch(socket: WebSocket, root: string) {
135135
});
136136
}
137137

138-
async function refreshMarkdown(path: string) {
138+
async function refreshMarkdown(path: string): Promise<WatchListener<string>> {
139139
let current = await readMarkdown(path, root);
140140
attachmentWatcher = new FileWatchers(root, current.parse.files, refreshAttachment(current.parse));
141-
return async (event: WatchEventType) => {
142-
if (event !== "change") return; // TODO: decide how to handle a "rename" event
143-
const updated = await readMarkdown(path, root);
144-
if (current.hash !== updated.hash) {
145-
send({
146-
type: "update",
147-
diff: diffMarkdown(current, updated),
148-
previousHash: current.hash,
149-
updatedHash: updated.hash
150-
});
151-
attachmentWatcher?.close();
152-
attachmentWatcher = new FileWatchers(root, updated.parse.files, refreshAttachment(updated.parse));
153-
current = updated;
141+
return async function watcher(event) {
142+
switch (event) {
143+
case "rename": {
144+
markdownWatcher?.close();
145+
try {
146+
markdownWatcher = watch(path, watcher);
147+
} catch (error) {
148+
if (isNodeError(error) && error.code === "ENOENT") {
149+
console.error(`file no longer exists: ${path}`);
150+
socket.terminate();
151+
return;
152+
}
153+
throw error;
154+
}
155+
setTimeout(() => watcher("change"), 150); // delay to avoid a possibly-empty file
156+
break;
157+
}
158+
case "change": {
159+
const updated = await readMarkdown(path, root);
160+
if (current.hash === updated.hash) break;
161+
const diff = diffMarkdown(current, updated);
162+
send({type: "update", diff, previousHash: current.hash, updatedHash: updated.hash});
163+
attachmentWatcher?.close();
164+
attachmentWatcher = new FileWatchers(root, updated.parse.files, refreshAttachment(updated.parse));
165+
current = updated;
166+
break;
167+
}
168+
default:
169+
throw new Error("Unrecognized event: " + event);
154170
}
155171
};
156172
}

0 commit comments

Comments
 (0)