@effectionx/fs
v0.2.0
Published
File system operations for Effection programs. This package wraps Node.js `fs/promises` APIs as Effection Operations with structured concurrency support.
Readme
FS
File system operations for Effection programs. This package wraps Node.js
fs/promises APIs as Effection Operations with structured concurrency support.
Installation
npm install @effectionx/fsBasic Usage
import { main } from "effection";
import { exists, readTextFile, writeTextFile } from "@effectionx/fs";
await main(function* () {
if (yield* exists("./config.json")) {
const config = yield* readTextFile("./config.json");
console.log(JSON.parse(config));
} else {
yield* writeTextFile("./config.json", JSON.stringify({ version: 1 }));
}
});File Operations
stat()
Get file or directory stats.
import { stat } from "@effectionx/fs";
const stats = yield* stat("./file.txt");
console.log(stats.isFile()); // true
console.log(stats.size); // file size in byteslstat()
Get file or directory stats without following symlinks.
import { lstat } from "@effectionx/fs";
const stats = yield* lstat("./symlink");
console.log(stats.isSymbolicLink()); // trueexists()
Check if a file or directory exists.
import { exists } from "@effectionx/fs";
if (yield* exists("./config.json")) {
console.log("Config file found");
}readTextFile()
Read a file as text.
import { readTextFile } from "@effectionx/fs";
const content = yield* readTextFile("./README.md");writeTextFile()
Write text to a file.
import { writeTextFile } from "@effectionx/fs";
yield* writeTextFile("./output.txt", "Hello, World!");ensureFile()
Ensure a file exists, creating parent directories and the file if needed.
import { ensureFile } from "@effectionx/fs";
yield* ensureFile("./data/logs/app.log");copyFile()
Copy a file.
import { copyFile } from "@effectionx/fs";
yield* copyFile("./source.txt", "./backup.txt");rm()
Remove a file or directory.
import { rm } from "@effectionx/fs";
// Remove a file
yield* rm("./temp.txt");
// Remove a directory recursively
yield* rm("./temp", { recursive: true });
// Force remove (no error if doesn't exist)
yield* rm("./maybe-exists", { force: true });Directory Operations
ensureDir()
Ensure a directory exists, creating it recursively if needed.
import { ensureDir } from "@effectionx/fs";
yield* ensureDir("./data/cache/images");readdir()
Read the contents of a directory.
import { readdir } from "@effectionx/fs";
const entries = yield* readdir("./src");
console.log(entries); // ["index.ts", "utils.ts", ...]emptyDir()
Empty a directory by removing all its contents. Creates the directory if it doesn't exist.
import { emptyDir } from "@effectionx/fs";
yield* emptyDir("./dist");walk()
Walk a directory tree and yield entries as a Stream.
import { walk } from "@effectionx/fs";
import { each } from "effection";
for (const entry of yield* each(walk("./src"))) {
if (entry.isFile && entry.name.endsWith(".ts")) {
console.log(entry.path);
}
yield* each.next();
}Each entry includes:
path- Full path to the entryname- Basename of the entryisFile- Whether it's a fileisDirectory- Whether it's a directoryisSymlink- Whether it's a symbolic link
Walk Options
walk("./src", {
includeDirs: true, // Include directories (default: true)
includeFiles: true, // Include files (default: true)
includeSymlinks: true, // Include symlinks (default: true)
match: [/\.ts$/], // Only include matching paths
skip: [/node_modules/], // Exclude matching paths
maxDepth: 3, // Maximum traversal depth
followSymlinks: false, // Follow symbolic links (default: false)
});expandGlob()
Expand glob patterns and yield matching paths as a Stream.
import { expandGlob } from "@effectionx/fs";
import { each } from "effection";
for (const entry of yield* each(expandGlob("./src/**/*.ts"))) {
console.log(entry.path);
yield* each.next();
}Glob Options
expandGlob("**/*.ts", {
root: "./src", // Root directory (default: ".")
exclude: ["**/*.test.ts"], // Patterns to exclude
includeDirs: false, // Include directories (default: true)
followSymlinks: false, // Follow symbolic links (default: false)
});Utilities
toPath()
Convert a path or URL to a file path string.
import { toPath } from "@effectionx/fs";
toPath("./file.txt"); // "./file.txt"
toPath(new URL("file:///tmp")); // "/tmp"globToRegExp()
Convert a glob pattern to a RegExp.
import { globToRegExp } from "@effectionx/fs";
const regex = globToRegExp("*.ts");
regex.test("file.ts"); // true
regex.test("file.js"); // false
// Supports extended glob syntax
globToRegExp("**/*.{ts,js}"); // Match .ts or .js files recursively
globToRegExp("file[0-9].txt"); // Character classes
globToRegExp("src/**/test?.ts"); // ? matches single characterURL Conversion
Re-exported from node:url for convenience:
import { fromFileUrl, toFileUrl } from "@effectionx/fs";
fromFileUrl(new URL("file:///tmp/file.txt")); // "/tmp/file.txt"
toFileUrl("/tmp/file.txt"); // URL { href: "file:///tmp/file.txt" }Path and URL Support
All file operations accept either a string path or a URL object:
import { readTextFile } from "@effectionx/fs";
// String path
yield* readTextFile("./config.json");
// URL object
yield* readTextFile(new URL("file:///etc/config.json"));
// import.meta.url based paths
yield* readTextFile(new URL("./data.json", import.meta.url));