Glob-pattern file watcher for MoonBit native — debounced, queue-aware, chokidar-backed.
moon add i5ting/glob-watcherimport {
"i5ting/glob-watcher" @glob_watcher,
"i5ting/chokidar",
}
options(
"warn-list": "-29",
)fn main {
try {
@glob_watcher.watch(
@chokidar.WatchPaths::One("**/*.{js,ts}"),
@glob_watcher.Options::default(),
event => println(event.name.to_string() + " " + event.path),
)
} catch {
@glob_watcher.GlobError(msg) => println("glob error: " + msg)
@glob_watcher.SetupError(msg) => println("setup error: " + msg)
}
}fn run() -> Unit raise @glob_watcher.GlobWatcherError {
let opts = @glob_watcher.Options::{
..@glob_watcher.Options::default(),
delay: 300, // ms to debounce
queue: true, // queue events while callback runs
ignore_initial: true, // skip pre-existing files
use_polling: false, // use native fs events (kqueue/inotify)
cwd: Some("src"), // resolve relative globs from here
}
let w = @glob_watcher.GlobWatcher::new(
@chokidar.WatchPaths::Many(["**/*.ts", "!**/*.d.ts"]),
opts,
)
w.on(@chokidar.EventName::Ready, _ => println("ready"))
|> ignore
w.run(cb=event =>
println(event.name.to_string() + " " + event.path)
)
}fn watch_adds_only() -> Unit raise @glob_watcher.GlobWatcherError {
let opts = @glob_watcher.Options::{
..@glob_watcher.Options::default(),
events: [@chokidar.EventName::Add], // fire only on new files
}
@glob_watcher.watch(
@chokidar.WatchPaths::One("uploads/**"),
opts,
event => println("new file: " + event.path),
)
}fn custom_loop(w : @glob_watcher.GlobWatcher) -> Unit raise @glob_watcher.GlobWatcherError {
loop {
// drive one debounce+queue cycle
w.tick(cb=event => println("changed: " + event.path))
// ... do other work here ...
}
}fn show_watched(w : @glob_watcher.GlobWatcher) -> Unit {
let dirs = w.get_watched()
for dir, files in dirs {
println(dir + ":")
for f in files {
println(" " + f)
}
}
}| Field | Type | Default | Description |
|---|---|---|---|
| delay | Int | 200 | Debounce window in ms |
| queue | Bool | true | Queue next event while callback is busy |
| events | Array[EventName] | [Add, Change, Unlink] | Event types that trigger the callback |
| ignore_initial | Bool | true | Skip files that exist before watch starts |
| ignored | Array[Matcher] | [] | Extra ignore matchers passed to chokidar |
| cwd | String? | None | Working directory for relative glob paths |
| depth | Int | Int::max_value | Maximum directory depth |
| loop_interval | Int | 10 | Polling interval for the run loop in ms |
| use_polling | Bool | true | Use polling instead of native fs events |
| Pattern | Matches |
|---|---|
| *.ts | Any .ts file in the root |
| **/*.ts | Any .ts file at any depth |
| src/**/*.{js,ts} | .js or .ts files under src/ |
| !vendor/** | Exclude anything under vendor/ |
pub fn watch(
glob : @chokidar.WatchPaths,
options : Options,
cb : (@chokidar.Event) -> Unit raise Error,
) -> Unit raise GlobWatcherErrorpub fn GlobWatcher::new(
glob : @chokidar.WatchPaths,
options : Options,
) -> GlobWatcher raise GlobWatcherErrorpub fn GlobWatcher::on(
self : GlobWatcher,
event : @chokidar.EventName,
callback : (@chokidar.Event) -> Unit,
) -> GlobWatcherpub fn GlobWatcher::run(
self : GlobWatcher,
cb? : (@chokidar.Event) -> Unit raise Error,
) -> Unit raise GlobWatcherErrorpub fn GlobWatcher::tick(
self : GlobWatcher,
cb? : (@chokidar.Event) -> Unit raise Error,
) -> Unit raise GlobWatcherErrorpub fn GlobWatcher::close(self : GlobWatcher) -> Unitpub fn GlobWatcher::get_watched(
self : GlobWatcher,
) -> Map[String, Array[String]]pub(all) suberror GlobWatcherError {
GlobError(String) // invalid or negation-only glob patterns
SetupError(String) // chokidar initialisation failure
}# basic demo — watch **/*.{js,ts} and print each change
moon run cmd/main --target native
# build-trigger demo — watch src/**/*.ts and simulate a rebuild
moon run cmd/rebuild --target nativemoon build --target native
moon test --target nativetype CallbackQueuetype Debouncerpub(all) struct GlobPattern {
raw : String
base_dir : String
is_negation : Bool
}pub struct GlobWatcher {
// private fields
}fn GlobWatcher::on(self : GlobWatcher, event : EventName, callback : (Event) -> Unit) -> GlobWatcherfn GlobWatcher::tick(self : GlobWatcher, cb? : (Event) -> Unit raise) -> Unit raise GlobWatcherErrorfn glob_match(pattern : String, path : String) -> Boolfn watch(glob : WatchPaths, options : Options, cb : (Event) -> Unit raise) -> Unit raise GlobWatcherErrorInstall
Download zipGlob-pattern file watcher for MoonBit native — debounced, queue-aware, chokidar-backed.