• This repository has been archived on 15/Dec/2022
  • Stars
    star
    200
  • Rank 195,325 (Top 4 %)
  • Language
    C++
  • License
    MIT License
  • Created over 7 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Atom Filesystem Watcher
Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our official announcement

Atom Filesystem Watcher

Greenkeeper badge

Linux Windows MacOS
Build Status Build status CircleCI

@atom/watcher is a filesystem watching library for Node.js built to power Atom. It prioritizes:

  • High fidelity to the native filesystem watching system calls provided by each operating system.
  • Graceful degredation to polling when native events are unavailable.
  • Be gentle on your CPU even while polling large directory trees by throttling system calls and never using spinlocks. Respect your RAM by capping the amount of persisted information. Stay out of the event loop's way by delivering filesystem events to JavaScript in batches.
  • Scalability to thousands of watched root directories and tens of thousands of files per root.
  • Comprehensible diagnostics and logging, including detailed reporting of operating system errors.

Installation

@atom/watcher is developed against Node.js 8, but it should work with any Node.js version that supports async/await. Your system must be able to build native Node.js modules. @atom/watcher supports MacOS (>= MacOS 10.7), Windows (>= Windows XP, >= Windows Server 2003), and Linux (kernel >= 2.6.27, glibc >= 2.9 👉 Ubuntu >= 10.04, Debian >= 6, RHEL >= 6).

$ npm install @atom/watcher

Use

To be notified when any filesystem event occurs beneath /var/log:

const watcher = require('@atom/watcher')

// Invoke a callback with each filesystem event that occurs beneath a specified path.
const w = await watcher.watchPath('/var/log', {}, events => {
  console.log(`Received batch of ${events.length} events.`)
  for (const event of events) {
    // "created", "modified", "deleted", "renamed"
    console.log(`Event action: ${event.action}`)

    // Absolute path to the filesystem entry that was touched
    console.log(`Event path: ${event.path}`)

    // "file", "directory", "symlink", or "unknown"
    console.log(`Event entry kind: ${event.kind}`)

    if (event.action === 'renamed') {
      console.log(`.. renamed from: ${event.oldPath}`)
    }
  }
})

// Report errors that occur after the watch root has been started.
w.onDidError(err => {
  console.error(`Something went wrong: ${err}`)
})

// Immediately stop receiving filesystem events. If this is the last watcher on this path, asynchronously release
// any OS resources required to subscribe to these events.
w.dispose()

configure()

Tweak package-global settings. This method may be called even after watchers have been started. The Promise it returns resolves when all changed settings have taken effect. All configuration settings are optional. Omitted keys are left unchanged.

const watcher = require('@atom/watcher')

await watcher.configure({
  jsLog: watcher.STDOUT,
  mainLog: watcher.STDERR,
  workerLog: 'worker.log',
  pollingLog: 'polling.log',
  workerCacheSize: 4096,
  pollingThrottle: 1000,
  pollingInterval: 100
})

jsLog configures the logging of events from the JavaScript layer. It may be one of:

  • A String specifying a path to log to a file. Be careful that you don't log to a directory that you're watching 😇
  • The constants watcher.STDERR or watcher.STDOUT to log to the node process' standard error or output streams.
  • watcher.DISABLE to disable main thread logging. This is the default.

mainLog configures the logging of events from the main thread, in line with libuv's event loop. It accepts the same arguments as jsLog and also defaults to watcher.DISABLE.

workerLog configures logging for the worker thread, which is used to interact with native operating system filesystem watching APIs. It accepts the same arguments as jsLog and also defaults to watcher.DISABLE.

pollingLog configures logging for the polling thread, which polls the filesystem when the worker thread is unable to. The polling thread only launches when at least one path needs to be polled. pollingLog accepts the same arguments as jsLog and also defaults to watcher.DISABLE.

workerCacheSize controls the number of recently seen stat results are cached within the worker thread. Increasing the cache size will improve the reliability of rename correlation and the entry kinds of deleted entries, but will consume more RAM. The default is 4096.

pollingThrottle controls the rough number of filesystem-touching system calls (lstat() and readdir()) performed by the polling thread on each polling cycle. Increasing the throttle will improve the timeliness of polled events, especially when watching large directory trees, but will consume more processor cycles and I/O bandwidth. The throttle defaults to 1000.

pollingInterval adjusts the time in milliseconds that the polling thread spends sleeping between polling cycles. Decreasing the interval will improve the timeliness of polled events, but will consume more processor cycles and I/O bandwidth. The interval defaults to 100.

watchPath()

Invoke a callback with each batch of filesystem events that occur beneath a specified directory.

const {watchPath} = require('@atom/watcher')
const watcher = await watchPath('/var/log', {recursive: true}, (events) => {
  // ...
})

The returned Promise resolves to a PathWatcher instance when the watcher is fully installed and events are flowing. The Promise may reject if the path does not exist, is not a directory, or if an operating system error prevented the watcher from successfully initializing, like a thread failing to launch or memory being exhausted.

The path argument specifies the root directory to watch. This must be an existing directory, but may be relative, contain symlinks, or contain . and .. segments. Multiple independent calls to watchPath() may result in PathWatcher instances backed by the same native event source or polling root, so it is relatively cheap to create many watchers within the same directory hierarchy across your codebase.

The options argument configures the nature of the watch. Pass {} to accept the defaults. Available options are:

  • recursive: If true, filesystem events that occur within subdirectories will be reported as well. If false, only changes to immediate children of the provided path will be reported. Defaults to true.

The callback argument will be called repeatedly with each batch of filesystem events that are delivered until the .dispose() method is called. Event batches are Arrays containing objects with the following keys:

  • action: a String describing the filesystem action that occurred. One of "created", "modified", "deleted", or "renamed".
  • kind: a String distinguishing the type of filesystem entry that was acted upon, if known. One of "file", "directory", "symlink", or "unknown".
  • path: a String containing the absolute path to the filesystem entry that was acted upon. In the event of a rename, this is the new path of the entry.
  • oldPath: a String containing the former absolute path of a renamed filesystem entry. Omitted when action is not "renamed".

The callback may be invoked for filesystem events that occur before the promise is resolved, but it will be invoked for any changes that occur after it resolves. All three arguments are mandatory.

🗒️ When writing tests against code that uses watchPath, note that you cannot easily assert that an event was not delivered. This is especially true on MacOS, where timestamp resolution can cause you to receive events that occurred before you even issued the watchPath call!

PathWatcher.onDidError()

Invoke a callback with any errors that occur after the watcher has been installed successfully.

const {watchPath} = require('@atom/watcher')
const watcher = await watchPath('/var/log', {}, () => {})

const disposable = watcher.onDidError(err => {
  console.error(err)
})

disposable.dispose()

Returns a Disposable that clients should dispose to release the subscription.

The callback argument will be invoked with an Error with a stack trace that likely isn't very helpful and a message that hopefully is.

PathWatcher.dispose()

Release an event subscription. The event callback associated with this PathWatcher will not be called after the watcher has been disposed, synchronously. Note that the native resources or polling root used to feed events to this watcher may remain, if another active PathWatcher is consuming events from it, and even if they are freed as a result of this disposal they will be freed asynchronously.

const {watchPath} = require('@atom/watcher')
const watcher = await watchPath('/var/log', {}, () => {})

//

watcher.dispose()

Environment variables

Logging may also be configured by setting environment variables. Each of these may be set to an empty string to disable that log, "stderr" to output to stderr, "stdout" to output to stdout, or a path to write output to a file at that path.

  • WATCHER_LOG_JS: JavaScript layer logging
  • WATCHER_LOG_MAIN: Main thread logging
  • WATCHER_LOG_WORKER: Worker thread logging
  • WATCHER_LOG_POLLING: Polling thread logging

CLI

It's possible to call @atom/watcher from the command-line, like this:

$ watcher /path/to/watch

Example:

created directory: /path/to/watch/foo
deleted directory: /path/to/watch/foo

It can be useful for testing the watcher and to describe a scenario when reporting an issue.

More Repositories

1

atom

:atom: The hackable text editor
JavaScript
59,608
star
2

teletype

Share your workspace with team members and collaborate on code in real time in Atom
JavaScript
2,406
star
3

vim-mode

Next generation vim support for atom
CoffeeScript
1,722
star
4

node-keytar

Native Password Node Module
C++
1,365
star
5

apm

Atom Package Manager
CoffeeScript
1,263
star
6

markdown-preview

📝 Markdown preview in Atom
JavaScript
1,235
star
7

github

:octocat: Git and GitHub integration for Atom
JavaScript
1,114
star
8

autocomplete-plus

View and insert possible completions in the editor while typing
JavaScript
960
star
9

teletype-crdt

String-wise sequence CRDT powering peer-to-peer collaborative editing in Teletype for Atom.
JavaScript
751
star
10

flight-manual.atom.io

📖 Documentation for Atom, generated by nanoc, hosted by GitHub Pages
SCSS
639
star
11

tree-view

🌳 Explore and open project files in Atom
CoffeeScript
564
star
12

etch

Builds components using a simple and explicit API around virtual-dom
JavaScript
555
star
13

highlights

Syntax highlighter
CoffeeScript
529
star
14

one-dark-syntax

Atom One dark syntax theme
CSS
447
star
15

atom-languageclient

Language Server Protocol support for Atom (the basis of Atom-IDE)
TypeScript
389
star
16

ide-typescript

TypeScript and Javascript language support for Atom-IDE
JavaScript
368
star
17

fuzzaldrin

Fuzzy filtering and string scoring
CoffeeScript
317
star
18

node-spellchecker

SpellChecker Node Module
C++
294
star
19

fuzzy-finder

Find and open files quickly
JavaScript
277
star
20

settings-view

🔧 Edit Atom settings
CoffeeScript
269
star
21

one-dark-ui

Atom One dark UI theme
CSS
265
star
22

ide-php

PHP language support for Atom-IDE
JavaScript
264
star
23

find-and-replace

Find and replace in a single buffer and in the project
JavaScript
244
star
24

ide-java

Java language support for Atom-IDE
JavaScript
227
star
25

electron-link

A module to bundle your electron app into a single file that can be used for V8 snapshots.
JavaScript
218
star
26

teletype-client

Editor-agnostic library managing client interaction for peer-to-peer collaborative editing in Teletype for Atom
JavaScript
210
star
27

spell-check

Spell check Atom package
JavaScript
206
star
28

snippets

Atom snippets package
JavaScript
200
star
29

language-javascript

JavaScript language package for Atom
CoffeeScript
196
star
30

language-python

Python package for Atom
CoffeeScript
188
star
31

sort-lines

An Atom package to sort lines of text
JavaScript
173
star
32

git-utils

Git Node Module
JavaScript
167
star
33

symbols-view

Jump to symbols in Atom
JavaScript
164
star
34

atom.io

🌐 A place for feedback on the atom.io website and package API
159
star
35

welcome

Welcome editor thats shows on first run
JavaScript
158
star
36

superstring

Native core components for Atom
JavaScript
152
star
37

text-buffer

Atom's underlying text buffer
JavaScript
144
star
38

bracket-matcher

Jump to brackets
JavaScript
142
star
39

metrics

Help improve Atom by sending usage statistics, exceptions and deprecations to the team.
JavaScript
139
star
40

node-oniguruma

Oniguruma Node Module
JavaScript
121
star
41

language-php

PHP package for Atom
CoffeeScript
120
star
42

teletype-server

Server-side application that facilitates peer discovery for collaborative editing sessions in Teletype
JavaScript
118
star
43

language-c

C support in Atom
CoffeeScript
117
star
44

command-palette

Command Palette in Atom
JavaScript
117
star
45

styleguide

A package to exercise all the UI components.
JavaScript
115
star
46

fs-plus

node's fs module with some helpful additions
CoffeeScript
108
star
47

language-html

HTML package for Atom
CoffeeScript
108
star
48

tabs

Tabs in Atom
CoffeeScript
107
star
49

language-go

Go language package for Atom
CoffeeScript
106
star
50

atom-keymap

Atom's selector-based keymap system
CoffeeScript
105
star
51

atom-dark-ui

The default dark ui theme for Atom
CSS
103
star
52

git-diff

Diff markers in Atom's gutter
JavaScript
102
star
53

language-ruby

Ruby package for Atom
Ruby
102
star
54

status-bar

Status bar for Atom
CoffeeScript
101
star
55

language-gfm

GitHub Flavored Markdown in Atom
CoffeeScript
101
star
56

eon

Real-Time Conflict-Free Version Control System
101
star
57

event-kit

Simple library for implementing and consuming evented APIs
JavaScript
96
star
58

whitespace

Atom whitespace package
JavaScript
94
star
59

node-pathwatcher

Path Watcher Node Module
CoffeeScript
94
star
60

open-on-github

Atom package for opening files on GitHub.com
JavaScript
94
star
61

package-generator

Package to generate new packages
JavaScript
91
star
62

first-mate

TextMate helpers
JavaScript
89
star
63

season

CSON Node Module
CoffeeScript
85
star
64

ci

Build your Atom packages
PowerShell
82
star
65

language-todo

TODO highlighting package for Atom
CoffeeScript
81
star
66

toggle-quotes

An Atom package to toggle between single and double quotes
JavaScript
77
star
67

one-light-ui

Atom One light UI theme
CSS
75
star
68

solarized-dark-syntax

Atom syntax theme using the dark Solarized colors
CSS
74
star
69

notifications

User notifications
CoffeeScript
74
star
70

autocomplete-emojis

autocomplete+ emoji autocompletion
CoffeeScript
74
star
71

autocomplete-css

CSS property name and value completions
CoffeeScript
69
star
72

ascii-art

Convert selected text to ascii art banner
JavaScript
68
star
73

one-light-syntax

Atom One light syntax theme
CSS
68
star
74

atom-ui

Atom's UI library
CSS
67
star
75

autosave

Autosaves buffers when they lose focus
JavaScript
64
star
76

language-sass

Sass package for Atom
CoffeeScript
63
star
77

atom-space-pen-views

Atom SpacePen views that previously lived in core.
CoffeeScript
63
star
78

language-java

Java package for Atom
CoffeeScript
62
star
79

language-csharp

C# language support for Atom
Python
62
star
80

keyboard-layout

Node module to read and observe the current keyboard layout
C++
61
star
81

autocomplete-html

HTML tag and attribute completions
JavaScript
60
star
82

underscore-plus

Underscore with some extensions
CoffeeScript
60
star
83

language-css

CSS package for Atom
CoffeeScript
59
star
84

atomdoc

Atom's documentation parser for JavaScript / CoffeeScript
JavaScript
58
star
85

language-coffee-script

CoffeeScript support in Atom
CoffeeScript
58
star
86

atom-dark-syntax

Atom Dark Syntax theme
CSS
57
star
87

ide-csharp

C# language support for Atom-IDE
JavaScript
56
star
88

theorist

A reactive model toolkit for CoffeeScript
CoffeeScript
51
star
89

language-clojure

Clojure package for Atom
Clojure
49
star
90

bookmarks

Bookmark editor lines in Atom
JavaScript
49
star
91

language-ruby-on-rails

Ruby on Rails package for Atom
CoffeeScript
48
star
92

language-mustache

Mustache package for Atom
CoffeeScript
47
star
93

template-syntax

A template atom syntax theme to build from
Less
46
star
94

autocomplete-snippets

Adds snippets to autocomplete+ suggestions
JavaScript
46
star
95

keybinding-resolver

Shows what a keybinding resolves to
JavaScript
44
star
96

editor-stats

Graph your keyboard activity
CoffeeScript
44
star
97

image-view

View images in an Atom editor
JavaScript
44
star
98

base16-tomorrow-dark-theme

Base16 Theme for Atom
CSS
41
star
99

pr-changelog

Generate a PR changelog between two refs
JavaScript
40
star
100

wrap-guide

Don't cross the line
CoffeeScript
40
star