diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-02-21 13:21:51 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-21 13:21:51 -0500 |
commit | bd640bc7e6a946dec4477afc64d8083e372660f6 (patch) | |
tree | cb08b999ad594dc0796fa1fefc588c0b86083066 /cli/js | |
parent | 754b8c65ad5adda2961c667a6b64ab59c130111d (diff) |
feat: Deno.fsEvents() (#3452)
Diffstat (limited to 'cli/js')
-rw-r--r-- | cli/js/deno.ts | 1 | ||||
-rw-r--r-- | cli/js/dispatch.ts | 2 | ||||
-rw-r--r-- | cli/js/fs_events.ts | 40 | ||||
-rw-r--r-- | cli/js/fs_events_test.ts | 52 | ||||
-rw-r--r-- | cli/js/lib.deno.ns.d.ts | 15 | ||||
-rw-r--r-- | cli/js/unit_tests.ts | 1 |
6 files changed, 111 insertions, 0 deletions
diff --git a/cli/js/deno.ts b/cli/js/deno.ts index b86b28911..d20c64281 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -43,6 +43,7 @@ export { OpenOptions, OpenMode } from "./files.ts"; +export { FsEvent, fsEvents } from "./fs_events.ts"; export { EOF, copy, diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts index 64a392ab9..3d2138953 100644 --- a/cli/js/dispatch.ts +++ b/cli/js/dispatch.ts @@ -73,6 +73,8 @@ export let OP_CWD: number; export let OP_CONNECT_TLS: number; export let OP_HOSTNAME: number; export let OP_OPEN_PLUGIN: number; +export let OP_FS_EVENTS_OPEN: number; +export let OP_FS_EVENTS_POLL: number; export let OP_COMPILE: number; export let OP_TRANSPILE: number; export let OP_SIGNAL_BIND: number; diff --git a/cli/js/fs_events.ts b/cli/js/fs_events.ts new file mode 100644 index 000000000..a4deff48a --- /dev/null +++ b/cli/js/fs_events.ts @@ -0,0 +1,40 @@ +// Copyright 2019 the Deno authors. All rights reserved. MIT license. +import { sendSync, sendAsync } from "./dispatch_json.ts"; +import * as dispatch from "./dispatch.ts"; +import { close } from "./files.ts"; + +export interface FsEvent { + kind: "any" | "access" | "create" | "modify" | "remove"; + paths: string[]; +} + +class FsEvents implements AsyncIterableIterator<FsEvent> { + readonly rid: number; + + constructor(paths: string[], options: { recursive: boolean }) { + const { recursive } = options; + this.rid = sendSync(dispatch.OP_FS_EVENTS_OPEN, { recursive, paths }); + } + + async next(): Promise<IteratorResult<FsEvent>> { + return await sendAsync(dispatch.OP_FS_EVENTS_POLL, { + rid: this.rid + }); + } + + async return(value?: FsEvent): Promise<IteratorResult<FsEvent>> { + close(this.rid); + return { value, done: true }; + } + + [Symbol.asyncIterator](): AsyncIterableIterator<FsEvent> { + return this; + } +} + +export function fsEvents( + paths: string | string[], + options = { recursive: true } +): AsyncIterableIterator<FsEvent> { + return new FsEvents(Array.isArray(paths) ? paths : [paths], options); +} diff --git a/cli/js/fs_events_test.ts b/cli/js/fs_events_test.ts new file mode 100644 index 000000000..161ee2ebf --- /dev/null +++ b/cli/js/fs_events_test.ts @@ -0,0 +1,52 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { testPerm, assert } from "./test_util.ts"; + +// TODO(ry) Add more tests to specify format. + +testPerm({ read: false }, function fsEventsPermissions() { + let thrown = false; + try { + Deno.fsEvents("."); + } catch (err) { + assert(err instanceof Deno.Err.PermissionDenied); + thrown = true; + } + assert(thrown); +}); + +async function getTwoEvents( + iter: AsyncIterableIterator<Deno.FsEvent> +): Promise<Deno.FsEvent[]> { + const events = []; + for await (const event of iter) { + console.log(">>>> event", event); + events.push(event); + if (events.length > 2) break; + } + return events; +} + +testPerm({ read: true, write: true }, async function fsEventsBasic(): Promise< + void +> { + const testDir = await Deno.makeTempDir(); + const iter = Deno.fsEvents(testDir); + + // Asynchornously capture two fs events. + const eventsPromise = getTwoEvents(iter); + + // Make some random file system activity. + const file1 = testDir + "/file1.txt"; + const file2 = testDir + "/file2.txt"; + Deno.writeFileSync(file1, new Uint8Array([0, 1, 2])); + Deno.writeFileSync(file2, new Uint8Array([0, 1, 2])); + + // We should have gotten two fs events. + const events = await eventsPromise; + console.log("events", events); + assert(events.length >= 2); + assert(events[0].kind == "create"); + assert(events[0].paths[0].includes(testDir)); + assert(events[1].kind == "create" || events[1].kind == "modify"); + assert(events[1].paths[0].includes(testDir)); +}); diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index 1839c813a..39303677a 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -1620,6 +1620,21 @@ declare namespace Deno { */ export function resources(): ResourceMap; + /** UNSTABLE: new API. Needs docs. */ + export interface FsEvent { + kind: "any" | "access" | "create" | "modify" | "remove"; + paths: string[]; + } + + /** UNSTABLE: new API. Needs docs. + * + * recursive option is true by default. + */ + export function fsEvents( + paths: string | string[], + options?: { recursive: boolean } + ): AsyncIterableIterator<FsEvent>; + /** How to handle subprocess stdio. * * "inherit" The default if unspecified. The child inherits from the diff --git a/cli/js/unit_tests.ts b/cli/js/unit_tests.ts index 0bdd17964..ec4505c21 100644 --- a/cli/js/unit_tests.ts +++ b/cli/js/unit_tests.ts @@ -23,6 +23,7 @@ import "./fetch_test.ts"; import "./file_test.ts"; import "./files_test.ts"; import "./form_data_test.ts"; +import "./fs_events_test.ts"; import "./get_random_values_test.ts"; import "./globals_test.ts"; import "./headers_test.ts"; |