Skip to content

Commit

Permalink
Merge pull request #141 from mcandeia/fix-watchers
Browse files Browse the repository at this point in the history
  • Loading branch information
james-pre authored Nov 20, 2024
2 parents 14cd605 + a375ff5 commit 0ea69a3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/emulation/watchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type * as fs from 'node:fs';
import { ErrnoError } from '../error.js';
import { isStatsEqual, type Stats } from '../stats.js';
import { normalizePath } from '../utils.js';
import { dirname, basename } from './path.js';
import { basename, dirname } from './path.js';
import { statSync } from './sync.js';

/**
Expand Down Expand Up @@ -171,23 +171,24 @@ export function removeWatcher(path: string, watcher: FSWatcher) {
}

export function emitChange(eventType: fs.WatchEventType, filename: string) {
let normalizedFilename: string = normalizePath(filename);
filename = normalizePath(filename);
// Notify watchers on the specific file
if (watchers.has(normalizedFilename)) {
for (const watcher of watchers.get(normalizedFilename)!) {
if (watchers.has(filename)) {
for (const watcher of watchers.get(filename)!) {
watcher.emit('change', eventType, basename(filename));
}
}

// Notify watchers on parent directories if they are watching recursively
let parent = dirname(normalizedFilename);
while (parent !== normalizedFilename && parent !== '/') {
let parent = filename,
normalizedFilename;
while (parent !== normalizedFilename) {
normalizedFilename = parent;
parent = dirname(parent);
if (watchers.has(parent)) {
for (const watcher of watchers.get(parent)!) {
watcher.emit('change', eventType, basename(filename));
watcher.emit('change', eventType, filename.slice(parent.length + (parent == '/' ? 0 : 1)));
}
}
normalizedFilename = parent;
parent = dirname(parent);
}
}
21 changes: 21 additions & 0 deletions tests/fs/watch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,27 @@ suite('Watch Features', () => {
resolve();
})();

await fs.promises.unlink(tempFile);
await promise;
});
test('fs.promises.watch should detect file creations recursively', async () => {
const rootDir = '/';
const subDir = `${testDir}sub-dir`;
const tempFile = `${subDir}/tempFile.txt`;
await fs.promises.mkdir(subDir);
const watcher = fs.promises.watch(rootDir);

await fs.promises.writeFile(tempFile, 'Temporary content');
const { promise, resolve } = Promise.withResolvers<void>();
(async () => {
for await (const event of watcher) {
assert.equal(event.eventType, 'rename');
assert.equal(event.filename, tempFile.substring(rootDir.length));
break;
}
resolve();
})();

await fs.promises.unlink(tempFile);
await promise;
});
Expand Down

0 comments on commit 0ea69a3

Please sign in to comment.