Documentation
¶
Overview ¶
Package watch provides file-system watching with debounced sync callbacks. Ported from src/sync/watcher.ts and src/sync/watch-policy.ts of github.com/colbymchenry/codegraph (MIT).
Index ¶
- Constants
- func DetectWSL() bool
- func EmitEventForTests(root, relPath string) bool
- func IsLockUnavailableError(err error) bool
- func ResetWSLCacheForTests()
- func WatchDisabledReason(projectRoot string, probe WatchProbe) string
- type FileWatcher
- type IsIgnoredFunc
- type IsSourceFileFunc
- type LockUnavailableError
- type NowFunc
- type Options
- type PendingFile
- type SyncFunc
- type SyncResult
- type WatchProbe
Constants ¶
const DefaultDebounceMS = 2000
DefaultDebounceMS is the default debounce delay before a sync is triggered after the last file-change event (2000 ms, matching the original).
const DefaultMaxDirWatches = 50_000
DefaultMaxDirWatches caps the number of simultaneously-watched directories on Linux (per-directory inotify path). Matches the original's 50 000.
Variables ¶
This section is empty.
Functions ¶
func DetectWSL ¶
func DetectWSL() bool
DetectWSL reports whether the current process is running under WSL. The result is cached after the first call.
func EmitEventForTests ¶
EmitEventForTests feeds a synthetic event to the live watcher registered for root. Returns false if no watcher is registered. For use in tests only.
func IsLockUnavailableError ¶
IsLockUnavailableError reports whether err is (or wraps) a LockUnavailableError.
func ResetWSLCacheForTests ¶
func ResetWSLCacheForTests()
ResetWSLCacheForTests resets the cached WSL detection so tests can control the outcome deterministically. Never call outside tests.
func WatchDisabledReason ¶
func WatchDisabledReason(projectRoot string, probe WatchProbe) string
WatchDisabledReason returns a human-readable reason why file watching should be skipped for projectRoot, or "" when watching should proceed.
Precedence (first match wins):
- CODEGRAPH_NO_WATCH=1 → off (explicit opt-out always wins)
- CODEGRAPH_FORCE_WATCH=1 → on (overrides auto-detection)
- WSL2 + /mnt/* drive → off (recursive fs.watch is too slow; #199)
Types ¶
type FileWatcher ¶
type FileWatcher struct {
// contains filtered or unexported fields
}
FileWatcher watches a project root for source-file changes and calls a debounced sync callback.
func New ¶
func New(root string, syncFn SyncFunc, opts Options) *FileWatcher
New creates a FileWatcher that has not yet started. Call FileWatcher.Start to begin watching.
func (*FileWatcher) IngestEventForTests ¶
func (fw *FileWatcher) IngestEventForTests(relPath string)
IngestEventForTests feeds a synthetic project-relative path through the full filter → pendingFiles → debounce pipeline. Only for use in tests.
func (*FileWatcher) IsActive ¶
func (fw *FileWatcher) IsActive() bool
IsActive reports whether the watcher is currently running.
func (*FileWatcher) PendingFiles ¶
func (fw *FileWatcher) PendingFiles() []PendingFile
PendingFiles returns a snapshot of files seen since the last successful sync.
func (*FileWatcher) Start ¶
func (fw *FileWatcher) Start() bool
Start begins watching. Returns true if watching started, false if disabled (e.g., CODEGRAPH_NO_WATCH or WSL2 /mnt drive).
func (*FileWatcher) Stop ¶
func (fw *FileWatcher) Stop()
Stop shuts down the watcher and clears state.
func (*FileWatcher) WaitUntilReady ¶
func (fw *FileWatcher) WaitUntilReady(timeout time.Duration) error
WaitUntilReady blocks until the watch set is established, or until the context deadline is reached.
type IsIgnoredFunc ¶
IsIgnoredFunc reports whether a project-relative POSIX path should be ignored entirely (not just non-source, but also not a directory to recurse into on Linux).
type IsSourceFileFunc ¶
IsSourceFileFunc reports whether a project-relative POSIX path is a source file that should be indexed.
type LockUnavailableError ¶
type LockUnavailableError struct {
// contains filtered or unexported fields
}
ErrLockUnavailable signals that the sync callback could not acquire the cross-process write lock. The watcher keeps pendingFiles intact and reschedules rather than reporting this as an error. Matches the original's LockUnavailableError.
func NewLockUnavailableError ¶
func NewLockUnavailableError(msg string) *LockUnavailableError
NewLockUnavailableError wraps a message as a LockUnavailableError.
func (*LockUnavailableError) Error ¶
func (e *LockUnavailableError) Error() string
type Options ¶
type Options struct {
// DebounceMs is the debounce delay in ms. 0 uses DefaultDebounceMS.
// Override via CODEGRAPH_WATCH_DEBOUNCE_MS env var (read at construction).
DebounceMs int
// OnSyncComplete is called after each successful sync.
OnSyncComplete func(SyncResult)
// OnSyncError is called when syncFn returns an error that is NOT
// ErrLockUnavailable.
OnSyncError func(error)
// IsSourceFile decides whether a project-relative path should be tracked.
// Defaults to a built-in set of Go/TS/JS extensions.
IsSourceFile IsSourceFileFunc
// IsIgnored decides whether a project-relative path should be dropped
// entirely (before the IsSourceFile check). Defaults to nil (nothing extra
// ignored beyond .codegraph/ and .git/).
IsIgnored IsIgnoredFunc
// Now overrides the clock. Defaults to time.Now.
Now NowFunc
// MaxDirWatches caps the Linux per-directory watch count. 0 = DefaultMaxDirWatches.
MaxDirWatches int
// InertForTests disables all OS-level watchers. Events are only fed
// through [FileWatcher.IngestEventForTests].
InertForTests bool
}
Options configures a FileWatcher.
type PendingFile ¶
type PendingFile struct {
// Path is the project-relative POSIX path (e.g. "src/foo.ts").
Path string
// FirstSeenMs is the wall-clock ms at the first event since the last sync.
FirstSeenMs int64
// LastSeenMs is the wall-clock ms at the most-recent event.
LastSeenMs int64
// Indexing is true when a sync is in flight that started after this
// file's most-recent event — meaning the next successful sync will
// absorb the edit.
Indexing bool
}
PendingFile is a source file the watcher observed since the last successful sync. Exposed via FileWatcher.PendingFiles so callers can flag stale results without blocking on a sync.
type SyncFunc ¶
type SyncFunc func() (SyncResult, error)
SyncFunc is the callback the watcher invokes after each debounce window. It should return ErrLockUnavailable when the cross-process write lock is held; the watcher retries without clearing pendingFiles in that case.
type SyncResult ¶
SyncResult is the value returned by a successful sync callback.
type WatchProbe ¶
type WatchProbe struct {
// Env overrides os.Environ lookups. nil means use os.Getenv.
Env map[string]string
// IsWSL overrides the WSL detection when non-nil.
IsWSL *bool
}
WatchProbe holds injectable inputs for WatchDisabledReason so tests can control the decision without touching real env vars or /proc/version.