Watch
The watch module exposes two ways to observe filesystem changes:
event-driven watching via watch.start (1.1.0, backed by
fsnotify) and a simple polling pair (snapshot / wait) for
scripts that prefer not to keep a callback alive.
Event-driven watching (watch.start)
import io;
import watch;
let handle = watch.start("config", func(dict<string, any> event): void {
io.println(event["type"] as string + " " + (event["path"] as string));
}, {"recursive": true});
# ... do other work; the callback fires for each event ...
watch.stop(handle);
Functions:
watch.start(path, callback): register a watcher on a file or directory; returns a handle. The callback receives an event dict for each filesystem event.watch.start(path, callback, {recursive: true}): walk subdirectories at start time and register each one (new directories created after registration are not auto-added).watch.stop(handle): stop the watcher and wait for the in-flight callback to finish before returning.
Event dict shape:
| Key | Type | Description |
|---|---|---|
path |
string |
Full path of the file the event refers to |
type |
string |
"create", "write", "remove", "rename", or "chmod" |
Callbacks fire on a worker goroutine. Mutations to module-level
state in the callback are visible to the parent after
watch.stop returns. Mutations to local closures are not
propagated back across goroutines, so collect into module-level
state when you need to observe events from outside the callback.
Polling (snapshot / wait)
Useful for tools and tests that just want to know whether something has changed since a known baseline.
import io;
import watch;
let changed = watch.wait("config/app.yaml", 5000);
if (changed["changed"] as bool) {
io.println("config changed");
}
Functions:
snapshot(path): capture the current state of a file or directory (returned as a dict).wait(path, timeoutMs = 30000, intervalMs = 250): take a fresh snapshot, then poll until the path changes or the timeout expires. Returns{"changed": bool, "before": dict, "after": dict}.intervalMscontrols the poll interval (default 250 ms).
Polling is fine for low-volume workloads. For high-volume
watching, prefer watch.start.