Filesystem observation layer for local-first systems.
The fs module is responsible for observing and describing changes in the local filesystem.
It is the entry point of all local data changes in Softadastra systems.
The goal of softadastra/fs is simple:
Detect changes in a directory and emit structured, reliable events.
Observe everything. Decide nothing.
This module:
- Detects changes
- Describes state
- Emits events
It does not decide what to do with them.
The fs module provides:
- Directory watching
- Initial filesystem scanning
- File state representation
- Snapshot creation
- Snapshot comparison (diff)
- Path utilities
- No sync logic (sync module)
- No durability (wal module)
- No network communication (transport module)
- No state ownership (metadata module)
π It is a pure observation layer.
The module observes changes but never triggers business logic.
Given the same filesystem state, it must produce the same results.
- Duplicate events are acceptable
- Missing events are not
No dependency on higher-level modules.
modules/fs/
βββ include/softadastra/fs/
β βββ Watcher.hpp
β βββ Scanner.hpp
β βββ PathUtils.hpp
β βββ FileState.hpp
β βββ Snapshot.hpp
βββ src/
Monitors a directory in real time.
Detects:
- File creation
- File modification
- File deletion
Performs an initial scan of a directory.
Used for:
- Bootstrapping state
- Rebuilding snapshots
Represents a file at a given moment.
Includes:
- Path
- Size
- Last modified time
- Optional hash
Represents the full state of a directory.
Used to:
- Compare states
- Detect differences
- Feed the sync engine
Utility helpers for:
- Path normalization
- Relative / absolute resolution
- Cross-platform handling
The module emits events such as:
FileCreatedFileUpdatedFileDeleted
Events can come from:
- Real-time watcher
- Snapshot diff
#include <softadastra/fs/watcher/Watcher.hpp>
#include <softadastra/fs/path/Path.hpp>
using namespace softadastra::fs;
int main()
{
watcher::Watcher watcher;
auto path = path::Path::from("./data").value();
watcher.start(path, [](const events::EventBatch &batch)
{
// handle filesystem changes
});
std::this_thread::sleep_for(std::chrono::minutes(1));
watcher.stop();
}Used by:
- sync (primary consumer)
- metadata (indirectly via sync)
To guarantee correctness:
- Watcher captures real-time events
- Snapshot diff acts as a fallback
- Event coalescing reduces noise
- softadastra/core
-
OS filesystem APIs:
- Linux: inotify
- macOS: FSEvents (planned)
- Windows: ReadDirectoryChangesW (planned)
- Single directory watcher
- Basic file events
- Snapshot diff support
- No advanced rename detection
- Rename detection (true move tracking)
- Ignore rules (.gitignore-style)
- Incremental hashing
- Large directory optimization
- Smarter event batching
- Never trigger sync directly
- Never store state permanently
- Never assume event completeness
- Always allow reconciliation via snapshot
The fs module is the eyes of the system.
It observes everything, but decides nothing.
- Detects filesystem changes
- Emits structured events
- Feeds the sync engine
- Fully decoupled
vix add @softadastra/fsSee root LICENSE file.