Cross-platform file watching library for MoonBit native target. Port of chokidar v5 with kqueue (macOS/FreeBSD) and inotify (Linux) backends.
moon add i5ting/chokidarfn main {
let watcher = @chokidar.watch(@chokidar.One("."))
watcher
.on(@chokidar.Add, event => println("added: " + event.path))
.on(@chokidar.Change, event => println("changed: " + event.path))
.on(@chokidar.Unlink, event => println("removed: " + event.path))
.on(@chokidar.Ready, _ => println("ready"))
|> ignore
// Drive the watcher in your application loop
while true {
watcher.process() catch { _ => () }
}
}pub fn watch(
paths : WatchPaths,
options? : Options,
) -> Watcher raise ChokidarError| Method | Description |
|---|---|
| add(paths) -> Watcher | Add more paths to watch |
| unwatch(paths) -> Watcher | Stop watching paths |
| on(event, callback) -> Watcher | Subscribe to an event |
| off(event, callback) -> Watcher | Unsubscribe a specific callback |
| remove_all_listeners() -> Watcher | Remove all event callbacks |
| get_watched() -> Map[String, Array[String]] | Return currently watched paths |
| close() -> Unit | Stop all watchers and clear state |
| process() -> Unit raise ChokidarError | Drain OS events and emit file-change events |
| EventName | Emitted when |
|---|---|
| Add | A file is added |
| AddDir | A directory is added |
| Change | A file changes |
| Unlink | A file is removed |
| UnlinkDir | A directory is removed |
| Ready | Initial scan complete (emitted once) |
| Raw | Raw OS event received |
| Error | A scan error occurs |
| All | Any of Add/AddDir/Change/Unlink/UnlinkDir |
pub struct Event {
name : EventName
path : String
stats : FileStats? // size, mode, modified_nanos
raw : RawEvent? // underlying OS event (Raw only)
error : ChokidarError? // (Error only)
}pub struct FileStats {
size : Int64
mode : Int
modified_nanos : Int64
}pub enum FileKind {
File
Directory
Symlink
Other // sockets, pipes, device nodes
}let watcher = @chokidar.watch(
@chokidar.One("src"),
options={
..@chokidar.Options::default(),
ignored: [
// exact path
@chokidar.MatchPath("src/generated.mbt"),
// recursive subtree
@chokidar.MatchRecursivePath("src/vendor"),
// regex
@chokidar.MatchRegex(@regexp.compile("\\.log$") |> Result::unwrap),
// function
@chokidar.MatchFunction((path, _stats) => path.has_suffix(".tmp")),
],
ignore_initial: true,
follow_symlinks: true,
cwd: Some("/project/root"),
use_polling: false,
interval: 100,
binary_interval: 300,
always_stat: false,
depth: 2147483647, // Int::max_value — unlimited
ignore_permission_errors: false,
atomic_option: @chokidar.AtomicDefault,
await_write_finish: @chokidar.AwaitWriteFinishOff,
}
)| Topic | chokidar-main (JS) | i5ting/chokidar (MoonBit) |
|---|---|---|
| Event model | Async callbacks via EventEmitter | Synchronous; call watcher.process() in a loop |
| close() | Returns Promise<void> | Synchronous Unit |
| on / off return type | FSWatcher (this) | Watcher (same behavior) |
| Event names | string literals: "add", "addDir" … | EventName enum variants; all_event_names() lists all nine |
| Matcher types | string, RegExp, function, { path, recursive? } | Matcher enum: MatchPath, MatchRecursivePath, MatchRegex, MatchFunction |
| ignored + cwd | MatchPath patterns are joined with cwd so absolute patterns work | MatchPath uses literal string equality; combine cwd into the pattern manually |
| Non-existent watch paths | Silently deferred until path appears | Raises ChokidarError on first scan |
| binaryInterval | Different poll interval for binary file extensions | Option accepted; uniform interval used |
| Special files | socket/FIFO/device nodes counted separately | Covered by FileKind::Other; emit Add/Unlink like regular files |
| JS name | MoonBit name | Note |
|---|---|---|
| FSWatcher | Watcher | |
| watch() | watch() | Same |
| FSWatcher.add() | Watcher::add() | Same |
| FSWatcher.on() | Watcher::on() | Same |
| FSWatcher.off() | Watcher::off() | Same |
| FSWatcher.unwatch() | Watcher::unwatch() | Same |
| FSWatcher.close() | Watcher::close() | Sync in MoonBit |
| FSWatcher.getWatched() | Watcher::get_watched() | snake_case |
| FSWatcher.removeAllListeners() | Watcher::remove_all_listeners() | snake_case |
| ignoreInitial | ignore_initial | snake_case |
| followSymlinks | follow_symlinks | snake_case |
| usePolling | use_polling | snake_case |
| binaryInterval | binary_interval | snake_case |
| alwaysStat | always_stat | snake_case |
| ignorePermissionErrors | ignore_permission_errors | snake_case |
| awaitWriteFinish | await_write_finish | snake_case |
| atomic | atomic_option | renamed (avoids keyword conflict) |
let watcher = @chokidar.watch(
@chokidar.One("src"),
options={
..@chokidar.Options::default(),
ignore_initial: true,
ignored: [@chokidar.MatchRecursivePath("src/node_modules")],
},
)
watcher.on(@chokidar.All, event => {
println(event.name.to_string() + " " + event.path)
}) |> ignorelet watcher = @chokidar.watch(
@chokidar.Many(["src", "test"]),
options={
..@chokidar.Options::default(),
ignore_initial: true,
},
)let watcher = @chokidar.watch(
@chokidar.One("uploads"),
options={
..@chokidar.Options::default(),
await_write_finish: @chokidar.AwaitWriteFinish::default_on(),
},
)let watcher = @chokidar.watch(
@chokidar.One("/mnt/share"),
options={
..@chokidar.Options::default(),
use_polling: true,
interval: 500,
},
)watcher.on(@chokidar.Change, event => {
match event.stats {
Some(s) => println("size: " + s.size.to_string())
None => ()
}
}) |> ignorelet cb : (@chokidar.Event) -> Unit = event => println(event.path)
watcher.on(@chokidar.Add, cb) |> ignore
// later...
watcher.off(@chokidar.Add, cb) |> ignorewatcher.close()| Variable | Effect |
|---|---|
| CHOKIDAR_USEPOLLING=true | 1 | Force use_polling: true |
| CHOKIDAR_USEPOLLING=false | 0 | Force use_polling: false |
| CHOKIDAR_INTERVAL=<ms> | Override interval |
pub(all) enum AwaitWriteFinish {
AwaitWriteFinishOff
AwaitWriteFinishOn(AwaitWriteFinishOptions)
} derive(Eq, Debug)pub(all) struct Options {
persistent : Bool
ignored : Array[Matcher]
ignore_initial : Bool
follow_symlinks : Bool
cwd : String?
use_polling : Bool
interval : Int
binary_interval : Int
always_stat : Bool
depth : Int
ignore_permission_errors : Bool
atomic_option : AtomicOption
await_write_finish : AwaitWriteFinish
}pub struct Watcher {
// private fields
}Install
Download zipCross-platform file watching library for MoonBit native target. Port of chokidar v5 with kqueue (macOS/FreeBSD) and inotify (Linux) backends.