Skip to content

Commit fd143f0

Browse files
bb-faceelliotBraem
andauthored
Switch from Gaze to Chokidar (#146)
* Switch from Gaze to Chokidar * Remove linter * upgrade packages * Update with absolute path * Add file path test for watcher --------- Co-authored-by: Elliot Braem <[email protected]>
1 parent 6f53366 commit fd143f0

File tree

6 files changed

+1020
-979
lines changed

6 files changed

+1020
-979
lines changed

lib/dev.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Gaze } from "gaze";
1+
import { FSWatcher } from "chokidar";
22
import path from "path";
33
import { Server as IoServer } from "socket.io";
44
import { buildApp } from "@/lib/build";
@@ -15,7 +15,7 @@ var appDevJsons = [];
1515
var appDevJsonPath = "bos-loader.json";
1616
var appDevOptions: null | DevOptions = null;
1717
let io: null | IoServer = null;
18-
let fileWatcher: null | Gaze = null;
18+
let fileWatcher: null | FSWatcher = null;
1919

2020
export type DevOptions = {
2121
port?: number; // port to run dev server

lib/watcher.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
import { Gaze } from "gaze";
1+
import path from "path"
2+
import chokidar, { FSWatcher } from "chokidar";
23

3-
export function startFileWatcher(watchPaths: string[], callback: Function): Gaze {
4-
const gaze = new Gaze(watchPaths, { debounceDelay: 100 });
4+
export function startFileWatcher(watchPaths: string[], callback: Function): FSWatcher {
5+
const watcher = chokidar.watch(watchPaths, {
6+
ignoreInitial: true,
7+
awaitWriteFinish: {
8+
stabilityThreshold: 100,
9+
pollInterval: 100
10+
}
11+
});
512

6-
// @ts-ignore
7-
gaze.on("all", callback);
13+
watcher.on('all', (event, relativePath) => {
14+
const absolutePath = path.resolve(relativePath)
15+
callback(event, absolutePath);
16+
});
817

9-
return gaze;
18+
return watcher;
1019
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
"@near-js/types": "^0.2.0",
3232
"axios": "^1.7.2",
3333
"body-parser": "^1.20.2",
34+
"chokidar": "^3.6.0",
3435
"commander": "^11.1.0",
3536
"crypto-js": "^4.2.0",
3637
"express": "^4.18.2",
3738
"fs-extra": "^11.2.0",
38-
"gaze": "^1.1.3",
3939
"glob": "^10.3.10",
4040
"http-proxy": "^1.18.1",
4141
"https": "^1.0.0",
@@ -55,7 +55,6 @@
5555
"@types/crypto-js": "^4.2.2",
5656
"@types/express": "^4.17.21",
5757
"@types/fs-extra": "^11.0.4",
58-
"@types/gaze": "^1.1.5",
5958
"@types/jest": "^29.5.11",
6059
"@types/node": "^20.11.30",
6160
"@types/supertest": "^6.0.2",

tests/unit/dev.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { startFileWatcher } from "@/lib/watcher";
88
import http from "http";
99
import path from "path";
1010
import { Server as IoServer } from "socket.io";
11-
import { Gaze } from "gaze";
11+
import chokidar from "chokidar";
1212

1313
import { vol } from 'memfs';
1414
jest.mock('fs', () => require('memfs').fs);
@@ -43,7 +43,6 @@ describe("dev", () => {
4343
(loadConfig as jest.MockedFunction<typeof loadConfig>).mockResolvedValue(mockConfig);
4444
(startDevServer as jest.MockedFunction<typeof startDevServer>).mockReturnValue({} as http.Server);
4545
(startSocket as jest.MockedFunction<typeof startSocket>).mockReturnValue(new IoServer());
46-
(startFileWatcher as jest.MockedFunction<typeof startFileWatcher>).mockReturnValue(new Gaze(mockSrc));
4746
(buildApp as jest.MockedFunction<typeof buildApp>).mockReturnValue({} as Promise<any>);
4847
});
4948

@@ -89,8 +88,16 @@ describe("dev", () => {
8988
});
9089

9190
it("should add correct watch paths after adding apps", async () => {
92-
const mockedGazeAdd = jest.spyOn(Gaze.prototype, 'add');
93-
91+
const mockAdd = jest.fn();
92+
const mockWatch = jest.fn().mockReturnValue({
93+
add: mockAdd,
94+
});
95+
(chokidar.watch as jest.Mock) = mockWatch;
96+
97+
(startFileWatcher as jest.MockedFunction<typeof startFileWatcher>).mockReturnValue(
98+
mockWatch([], {}) as chokidar.FSWatcher
99+
);
100+
94101
const mockOpts: DevOptions = { hot: false };
95102
await dev(mockSrc, "build", mockOpts);
96103

@@ -106,6 +113,6 @@ describe("dev", () => {
106113
path.join(mockSrc2, 'bos.config.json'),
107114
path.join(mockSrc2, 'aliases.json'),
108115
];
109-
expect(mockedGazeAdd).toHaveBeenCalledWith(expectedWatchPaths);
116+
expect(mockAdd).toHaveBeenCalledWith(expectedWatchPaths);
110117
});
111118
});

tests/unit/devNoMock.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { startFileWatcher } from "@/lib/watcher";
2+
import path from "path";
3+
import fs from "fs";
4+
5+
describe("File Watcher Tests", () => {
6+
let watcher;
7+
const tempDirPath = path.join(__dirname, "temp-test");
8+
9+
it("should call the file watcher callback with the correct attributes", async () => {
10+
const mockCallback = jest.fn();
11+
12+
fs.mkdirSync(tempDirPath, { recursive: true });
13+
14+
const tempFilePath = path.join(tempDirPath, "temp-file.txt");
15+
16+
const relativeTempFilePath = path.relative("./", tempFilePath)
17+
18+
fs.writeFileSync(tempFilePath, "initial content");
19+
20+
watcher = startFileWatcher([relativeTempFilePath], mockCallback);
21+
22+
await new Promise((resolve) => setTimeout(resolve, 1000));
23+
24+
fs.appendFileSync(tempFilePath, "\nadded content");
25+
26+
await new Promise((resolve) => setTimeout(resolve, 1000));
27+
28+
expect(mockCallback).toHaveBeenCalled();
29+
expect(mockCallback.mock.calls[0][0]).toBe("change");
30+
expect(mockCallback.mock.calls[0][1]).toBe(path.resolve(tempFilePath));
31+
});
32+
33+
afterAll(async () => {
34+
if (watcher) await watcher.close();
35+
36+
if (fs.existsSync(tempDirPath)) {
37+
fs.rmSync(tempDirPath, { recursive: true, force: true });
38+
}
39+
});
40+
});

0 commit comments

Comments
 (0)