From 595700c993891ec8bf83f455a6602070ab8351ac Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Tue, 1 Jun 2021 15:35:06 +0900 Subject: [PATCH] feat: add FsWatcher interface (#10798) --- cli/dts/lib.deno.ns.d.ts | 27 ++++++++++++++++++++++----- cli/tests/unit/fs_events_test.ts | 22 +++++++++++++++++++++- runtime/js/40_fs_events.js | 6 ++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index 58782e1b0c..c8b4b60a05 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -1949,6 +1949,25 @@ declare namespace Deno { paths: string[]; } + /** + * FsWatcher is returned by `Deno.watchFs` function when you start watching + * the file system. You can iterate over this interface to get the file + * system events, and also you can stop watching the file system by calling + * `.close()` method. + */ + export interface FsWatcher extends AsyncIterable { + /** The resource id of the `FsWatcher`. */ + readonly rid: number; + /** Stops watching the file system and closes the watcher resource. */ + close(): void; + /** @deprecated + * Stops watching the file system and closes the watcher resource. + * Will be removed at 2.0. + */ + return?(value?: any): Promise>; + [Symbol.asyncIterator](): AsyncIterableIterator; + } + /** Watch for file system events against one or more `paths`, which can be files * or directories. These paths must exist already. One user action (e.g. * `touch test.file`) can generate multiple file system events. Likewise, @@ -1967,15 +1986,13 @@ declare namespace Deno { * * Requires `allow-read` permission. * - * Call `watcher.return()` to stop watching. + * Call `watcher.close()` to stop watching. * * ```ts * const watcher = Deno.watchFs("/"); * * setTimeout(() => { - * if (watcher.return) { - * watcher.return(); - * } + * watcher.close(); * }, 5000); * * for await (const event of watcher) { @@ -1986,7 +2003,7 @@ declare namespace Deno { export function watchFs( paths: string | string[], options?: { recursive: boolean }, - ): AsyncIterableIterator; + ): FsWatcher; export class Process { readonly rid: number; diff --git a/cli/tests/unit/fs_events_test.ts b/cli/tests/unit/fs_events_test.ts index 0b30a070d5..87f3ec241e 100644 --- a/cli/tests/unit/fs_events_test.ts +++ b/cli/tests/unit/fs_events_test.ts @@ -26,7 +26,7 @@ unitTest({ perms: { read: true } }, function watchFsInvalidPath() { }); async function getTwoEvents( - iter: AsyncIterableIterator, + iter: Deno.FsWatcher, ): Promise { const events = []; for await (const event of iter) { @@ -61,6 +61,8 @@ unitTest( }, ); +// TODO(kt3k): This test is for the backward compatibility of `.return` method. +// This should be removed at 2.0 unitTest( { perms: { read: true, write: true } }, async function watchFsReturn(): Promise { @@ -78,3 +80,21 @@ unitTest( assertEquals(events, []); }, ); + +unitTest( + { perms: { read: true, write: true } }, + async function watchFsClose(): Promise { + const testDir = await Deno.makeTempDir(); + const iter = Deno.watchFs(testDir); + + // Asynchronously loop events. + const eventsPromise = getTwoEvents(iter); + + // Close the watcher. + await iter.close(); + + // Expect zero events. + const events = await eventsPromise; + assertEquals(events, []); + }, +); diff --git a/runtime/js/40_fs_events.js b/runtime/js/40_fs_events.js index a1a9877b42..48060e23a5 100644 --- a/runtime/js/40_fs_events.js +++ b/runtime/js/40_fs_events.js @@ -33,11 +33,17 @@ } } + // TODO(kt3k): This is deprecated. Will be removed in v2.0. + // See https://github.com/denoland/deno/issues/10577 for details return(value) { core.close(this.rid); return Promise.resolve({ value, done: true }); } + close() { + core.close(this.rid); + } + [Symbol.asyncIterator]() { return this; }