Hooks
Monitor and debug file system operations with hooks
Hooks System
All file system bridges support a hook system that allows you to listen to file system events. This is useful for monitoring, debugging, logging, and performance tracking.
Overview
Hooks are event listeners that are called at specific points during bridge operations. Each operation has before and after hooks, and there's also a global error hook for error handling.
Basic Usage
import NodeFileSystemBridge from "@ucdjs/fs-bridge/bridges/node";
const bridge = NodeFileSystemBridge({
basePath: "/path/to/directory"
});
// Register a hook
bridge.hook("read:before", (payload) => {
console.log(`Reading file: ${payload.path}`);
});
// Use the bridge normally
const content = await bridge.read("file.txt");
// Console: "Reading file: file.txt"Available Hooks
Prop
Type
Best Practices
When working with hooks, keep these guidelines in mind:
- Keep hooks lightweight: Hooks are called synchronously and can impact performance. Keep hook logic fast and avoid blocking operations.
- Don't modify payloads: The payload objects are shared. Modifying them can lead to unexpected behavior.
- Handle errors gracefully: If your hook logic can fail, wrap it in try-catch to prevent breaking the operation.
- Use hooks for observability: Hooks are perfect for logging, monitoring, and debugging, but avoid complex business logic.
- Clean up when needed: If you're tracking state in hooks (like timings), make sure to clean up to avoid memory leaks.
- Consider performance: Registering many hooks or heavy hook logic can slow down operations. Profile if performance is critical.
Hook Execution Order
Hooks are executed in the order they were registered:
- All
beforehooks are executed sequentially - The operation is performed
- All
afterhooks are executed sequentially
If a before hook throws an error, the operation will not be performed, and after hooks will not be called. The error hook will be triggered.
You can register multiple hooks for the same event:
bridge.hook("read:before", (payload) => {
console.log("Hook 1: Reading", payload.path);
});
bridge.hook("read:before", (payload) => {
console.log("Hook 2: Reading", payload.path);
});
// Both hooks will be called when reading a file
await bridge.read("file.txt");Use Cases
Log all file system operations for debugging:
bridge.hook("read:before", (payload) => {
logger.info(`Reading file: ${payload.path}`);
});
bridge.hook("error", (payload) => {
logger.error(`Operation failed: ${payload.method} on ${payload.path}`, payload.error);
});Track operation performance:
const timings = new Map<string, number>();
bridge.hook("read:before", (payload) => {
timings.set(payload.path, Date.now());
});
bridge.hook("read:after", (payload) => {
const startTime = timings.get(payload.path);
if (startTime) {
const duration = Date.now() - startTime;
console.log(`Read ${payload.path} took ${duration}ms`);
timings.delete(payload.path);
}
});