diff --git a/lib/dev.ts b/lib/dev.ts index 2bb4e88..367bfb5 100644 --- a/lib/dev.ts +++ b/lib/dev.ts @@ -1,4 +1,3 @@ -import { Gaze } from "gaze"; import path from "path"; import { Server as IoServer } from "socket.io"; import { buildApp } from "@/lib/build"; @@ -9,13 +8,14 @@ import { Network } from "@/lib/types"; import { loopThroughFiles, readFile, readJson, writeJson } from "@/lib/utils/fs"; import { mergeDeep, substractDeep } from "@/lib/utils/objects"; import { startFileWatcher } from "@/lib/watcher"; +import { FSWatcher } from "chokidar"; var appSrcs = [], appDists = []; var appDevJsons = []; var appDevJsonPath = "bos-loader.json"; var appDevOptions: null | DevOptions = null; let io: null | IoServer = null; -let fileWatcher: null | Gaze = null; +let fileWatcher: null | FSWatcher = null; export type DevOptions = { port?: number; // port to run dev server diff --git a/lib/watcher.ts b/lib/watcher.ts index 1cd0ba8..0b7552a 100644 --- a/lib/watcher.ts +++ b/lib/watcher.ts @@ -1,10 +1,16 @@ -import { Gaze } from "gaze"; +import chokidar, { FSWatcher } from "chokidar"; -export function startFileWatcher(watchPaths: string[], callback: Function): Gaze { - const gaze = new Gaze(watchPaths, { debounceDelay: 100 }); +export function startFileWatcher(watchPaths: string[], callback: Function): FSWatcher { + const watcher = chokidar.watch(watchPaths, { + ignoreInitial: true, + awaitWriteFinish: { + stabilityThreshold: 100, + pollInterval: 100 + } + }); - // @ts-ignore - gaze.on("all", callback); - - return gaze; + watcher.on('all', (event, path) => { + callback(); + }); + return watcher; } \ No newline at end of file diff --git a/package.json b/package.json index 99dc15e..8ee73a3 100644 --- a/package.json +++ b/package.json @@ -31,11 +31,11 @@ "@near-js/types": "^0.2.0", "axios": "^1.7.2", "body-parser": "^1.20.2", + "chokidar": "^3.6.0", "commander": "^11.1.0", "crypto-js": "^4.2.0", "express": "^4.18.2", "fs-extra": "^11.2.0", - "gaze": "^1.1.3", "glob": "^10.3.10", "http-proxy": "^1.18.1", "https": "^1.0.0", @@ -55,7 +55,6 @@ "@types/crypto-js": "^4.2.2", "@types/express": "^4.17.21", "@types/fs-extra": "^11.0.4", - "@types/gaze": "^1.1.5", "@types/jest": "^29.5.11", "@types/node": "^20.11.30", "@types/supertest": "^6.0.2", diff --git a/tests/unit/dev.ts b/tests/unit/dev.ts index 96b7a3d..cfbfa2f 100644 --- a/tests/unit/dev.ts +++ b/tests/unit/dev.ts @@ -8,7 +8,7 @@ import { startFileWatcher } from "@/lib/watcher"; import http from "http"; import path from "path"; import { Server as IoServer } from "socket.io"; -import { Gaze } from "gaze"; +import chokidar from "chokidar"; import { vol } from 'memfs'; jest.mock('fs', () => require('memfs').fs); @@ -43,7 +43,6 @@ describe("dev", () => { (loadConfig as jest.MockedFunction).mockResolvedValue(mockConfig); (startDevServer as jest.MockedFunction).mockReturnValue({} as http.Server); (startSocket as jest.MockedFunction).mockReturnValue(new IoServer()); - (startFileWatcher as jest.MockedFunction).mockReturnValue(new Gaze(mockSrc)); (buildApp as jest.MockedFunction).mockReturnValue({} as Promise); }); @@ -79,33 +78,44 @@ describe("dev", () => { it("should call startFileWatcher with correct watch paths", async () => { await dev(mockSrc, "build", mockOpts); const expectedWatchPaths = [ - path.join(mockSrc, 'widget', '**', '*'), - path.join(mockSrc, 'module', '**', '*'), - path.join(mockSrc, 'ipfs', '**', '*'), - path.join(mockSrc, 'bos.config.json'), - path.join(mockSrc, 'aliases.json'), + path.join(mockSrc, "widget", "**", "*"), + path.join(mockSrc, "module", "**", "*"), + path.join(mockSrc, "ipfs", "**", "*"), + path.join(mockSrc, "bos.config.json"), + path.join(mockSrc, "aliases.json"), ]; - expect(startFileWatcher).toHaveBeenCalledWith(expectedWatchPaths, expect.any(Function)); + expect(startFileWatcher).toHaveBeenCalledWith( + expectedWatchPaths, + expect.any(Function) + ); }); it("should add correct watch paths after adding apps", async () => { - const mockedGazeAdd = jest.spyOn(Gaze.prototype, 'add'); - + const mockAdd = jest.fn(); + const mockWatch = jest.fn().mockReturnValue({ + add: mockAdd, + }); + (chokidar.watch as jest.Mock) = mockWatch; + + (startFileWatcher as jest.MockedFunction).mockReturnValue( + mockWatch([], {}) as chokidar.FSWatcher + ); + const mockOpts: DevOptions = { hot: false }; await dev(mockSrc, "build", mockOpts); const mockSrc2 = "/app_example_2"; vol.fromJSON(app_example_2, mockSrc2); - const mockDist2 = path.join(mockSrc2, 'build'); + const mockDist2 = path.join(mockSrc2, "build"); await addApps([mockSrc2], [mockDist2]); const expectedWatchPaths = [ - path.join(mockSrc2, 'widget', '**', '*'), - path.join(mockSrc2, 'module', '**', '*'), - path.join(mockSrc2, 'ipfs', '**', '*'), - path.join(mockSrc2, 'bos.config.json'), - path.join(mockSrc2, 'aliases.json'), + path.join(mockSrc2, "widget", "**", "*"), + path.join(mockSrc2, "module", "**", "*"), + path.join(mockSrc2, "ipfs", "**", "*"), + path.join(mockSrc2, "bos.config.json"), + path.join(mockSrc2, "aliases.json"), ]; - expect(mockedGazeAdd).toHaveBeenCalledWith(expectedWatchPaths); + expect(mockAdd).toHaveBeenCalledWith(expectedWatchPaths); }); }); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 76a15bc..b54573e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -852,11 +852,6 @@ "@types/jsonfile" "*" "@types/node" "*" -"@types/gaze@^1.1.5": - version "1.1.5" - resolved "https://registry.npmjs.org/@types/gaze/-/gaze-1.1.5.tgz" - integrity sha512-EUsdBWbKIDvlsPBhEPA8LMbpvJaUjr/APU89uPbfPoXdPOw9Q6beEhB3oyYBn621j6s8zUiR5OVhbyJLA/Ij/A== - "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" @@ -1383,6 +1378,21 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + ci-info@^3.2.0: version "3.9.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" @@ -2042,13 +2052,6 @@ function-bind@^1.1.2: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -gaze@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz" - integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== - dependencies: - globule "^1.0.0" - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -2121,18 +2124,6 @@ glob@^8.1.0: minimatch "^5.0.1" once "^1.3.0" -glob@~7.1.1: - version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -2150,15 +2141,6 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" -globule@^1.0.0: - version "1.3.4" - resolved "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz" - integrity sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg== - dependencies: - glob "~7.1.1" - lodash "^4.17.21" - minimatch "~3.0.2" - gopd@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" @@ -2988,11 +2970,6 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" @@ -3039,7 +3016,7 @@ lodash.memoize@4.x: resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== -lodash@^4.17.11, lodash@^4.17.21: +lodash@^4.17.11: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3154,7 +3131,7 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4, minimatch@~3.0.2: +minimatch@^3.0.4: version "3.0.8" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz" integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q== @@ -3251,15 +3228,6 @@ negotiator@0.6.3: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -nock@^13.5.4: - version "13.5.4" - resolved "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz#8918f0addc70a63736170fef7106a9721e0dc479" - integrity sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - propagate "^2.0.0" - node-fetch@2.6.7: version "2.6.7" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" @@ -3484,11 +3452,6 @@ prompts@^2.0.1, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -propagate@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" - integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== - proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" @@ -3851,16 +3814,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3878,14 +3832,7 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4334,16 +4281,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==