diff --git a/package.json b/package.json index 5ed9de59e..63ce9fa1a 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,13 @@ "url": "https://github.com/streamich/memfs.git" }, "dependencies": { + "callback-to-async-iterator": "^1.1.1", "fs-monkey": "1.0.3" }, "devDependencies": { + "@semantic-release/changelog": "5.0.1", + "@semantic-release/git": "9.0.1", + "@semantic-release/npm": "8.0.0", "@types/jest": "27.0.1", "@types/node": "10.17.60", "cpy-cli": "3.1.1", @@ -34,15 +38,12 @@ "prettier": "2.4.1", "pretty-quick": "3.1.1", "rimraf": "3.0.2", + "semantic-release": "18.0.0", "ts-jest": "27.0.5", "ts-node": "10.2.1", "tslint": "5.20.1", "tslint-config-common": "1.6.0", - "typescript": "4.4.3", - "semantic-release": "18.0.0", - "@semantic-release/changelog": "5.0.1", - "@semantic-release/git": "9.0.1", - "@semantic-release/npm": "8.0.0" + "typescript": "4.4.3" }, "config": { "commitizen": { diff --git a/src/__tests__/util.ts b/src/__tests__/util.ts index abf640c49..6e60a2e1e 100644 --- a/src/__tests__/util.ts +++ b/src/__tests__/util.ts @@ -1,7 +1,7 @@ import { createFsFromVolume, Volume } from '..'; import { Link, Node } from '../node'; -export const create = (json: { [s: string]: string } = { '/foo': 'bar' }) => { +export const create = (json: { [s: string]: string | null } = { '/foo': 'bar' }) => { const vol = Volume.fromJSON(json); return vol; }; diff --git a/src/__tests__/volume/watchPromise.test.ts b/src/__tests__/volume/watchPromise.test.ts new file mode 100644 index 000000000..b742d2da4 --- /dev/null +++ b/src/__tests__/volume/watchPromise.test.ts @@ -0,0 +1,10 @@ +import { create } from '../util'; + +describe('promises.watch(path, options)', () => { + it('emits filesystem events', async () => { + const vol = create({foo: 'a'}); + // const iterator = vol.promises.watch('/foo', {}); + + // console.log(iterator); + }); +}); diff --git a/src/promises.ts b/src/promises.ts index cf2af80ef..b734e2b06 100644 --- a/src/promises.ts +++ b/src/promises.ts @@ -14,11 +14,13 @@ import { IWriteFileOptions, IStatOptions, IRmOptions, + IWatchOptions, } from './volume'; import Stats from './Stats'; import Dirent from './Dirent'; import { TDataOut } from './encoding'; import { PathLike, symlink } from 'fs'; +import asyncify from 'callback-to-async-iterator'; function promisify( vol: Volume, @@ -94,6 +96,7 @@ export interface IPromisesAPI { unlink(path: PathLike): Promise; utimes(path: PathLike, atime: TTime, mtime: TTime): Promise; writeFile(id: TFileHandle, data: TData, options?: IWriteFileOptions): Promise; + watch(path: PathLike, options?: string | IWatchOptions): AsyncIterator<{eventType: string, filename: string | Buffer}>; } export class FileHandle implements IFileHandle { @@ -274,5 +277,13 @@ export default function createPromisesApi(vol: Volume): null | IPromisesAPI { writeFile(id: TFileHandle, data: TData, options?: IWriteFileOptions): Promise { return promisify(vol, 'writeFile')(id instanceof FileHandle ? id.fd : (id as PathLike), data, options); }, + + watch(path: PathLike, options?: string | IWatchOptions): AsyncIterator<{eventType: string, filename: string | Buffer}> { + return asyncify((callback) => { + vol.watch(path, options || 'utf8', (eventType, filename) => { + callback({eventType, filename}); + }); + }); + } }; } diff --git a/src/volume.ts b/src/volume.ts index 9d2b84083..405fca251 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -2193,11 +2193,11 @@ export class Volume { return new this.WriteStream(path, options); } - // watch(path: PathLike): FSWatcher; - // watch(path: PathLike, options?: IWatchOptions | string): FSWatcher; + watch(path: PathLike, listener: (eventType: string, filename: string) => void): FSWatcher; + watch(path: PathLike, options: IWatchOptions | string, listener: (eventType: string, filename: string) => void): FSWatcher; watch( path: PathLike, - options?: IWatchOptions | string, + options: (IWatchOptions | string) | ((eventType: string, filename: string) => void), listener?: (eventType: string, filename: string) => void, ): FSWatcher { const filename = pathToFilename(path); diff --git a/yarn.lock b/yarn.lock index 7766b9838..021cd9bcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1945,6 +1945,13 @@ call-me-maybe@^1.0.1: resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +callback-to-async-iterator@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/callback-to-async-iterator/-/callback-to-async-iterator-1.1.1.tgz#110adcde834589bee475415baf0123b6a541c398" + integrity sha512-w5uOapjkp/CEizuvBkLl7JyHlQNlxAT7LSr9g4vFjg5AEM5TJvaajjKkgs4kcFFm0fNqFX9D0zEIotllXvNC1Q== + dependencies: + iterall "^1.0.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -3732,6 +3739,11 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +iterall@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + java-properties@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-1.0.2.tgz#ccd1fa73907438a5b5c38982269d0e771fe78211"