npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fstack

v0.2.27

Published

The missing filesystem wrangler for Node.js.

Downloads

21

Readme

fstack

Build Status NPM version Dependency Status

A lightweight and efficient driver stack to easily manage and maintain a filesystem. fstack is the missing filesystem wrangler for Node.js.

fstack provides a simple and optimized interface for accessing a filesystem and deriving logical structures by utilizing the fs core library. fstack features high-level filesystem operations such as asynchronous atomic implementations of copy, move, rm -rf, and mkdir -p. fstack can also derive a filesystem tree object based on a supplied path, providing numerous solutions for filesystem dependent applications. fstack is designed to replace other npm packages such as fs-extra, file, and node-dir. fstack also extends path and os, for convenience.

fstack's implementations of mkdir -p and rm -rf are more efficient than those found in the mkdirp and rimraf packages, respectively.

Read more on why rimraf is a hack.

Installing

npm install --save fstack

Usage

var fstack = require('fstack');

Benchmark (As of 0.2.18)

i in {0..99} `mkdir -p (i)\(i * 2)`
mkdirp 0 s, 9.906 ms
fstack 0 s, 3.743 ms
i in {0..99} `rm -rf i`
rimraf 0 s, 23.996 ms
fstack 0 s, 16.413 ms

Documentation

fstack.ents(path, callback, [stat])

fstack.ents(path, callback, [stat]) will return all of the immediate child entities inside path and callback with (err, ents), where ents is an array containing entity names if stat is not specified, and will callback with (err, ents, stats) if stat is specified.

/*
foo/
    bar/
        baz
    qux
*/

fstack.ents('./foo', function(err, ents) {
    console.log(ents);
});

// ['bar', 'qux']

fstack.dirs(path, callback)

fstack.dirs(path, callback) will return all of the immediate child directories inside path and callback with (err, dirs), where dirs is an associative array containing directory names as keys and stats as values.

/*
foo/
    bar/
        baz
    qux
*/

fstack.dirs('./foo', function(err, dirs) {
    console.log(dirs);
});

// ['bar']

fstack.files(path, callback)

fstack.ents(path, callback) will return all of the immediate child non-directories inside path and callback with (err, files), where files is an associative array containing non-directory names as keys and stats as values.

/*
foo/
    bar/
        baz
    qux
*/

fstack.files('./foo', function(err, files) {
    console.log(files);
});

// ['qux']

fstack.fst(path, callback, [depth])

fstack.fst(path, callback, [depth]) will callback with (err, fst), where fst is an object representing the filesystem with path as the root node. depth is the number of levels to recursively crawl the filesystem, and defaults to null, which does a complete crawl. Calling fstack#fst with a depth of 1 or 2 is a good strategy for returning an object that will represent a filesystem client-side. Directories will contain an object representing its children, while non-directories will contain their device types, which is usually 'file'.

/*
foo/
    bar/
        baz
    quux/
        corge/
            garply
        grault
    qux
*/

fstack.fst('./foo', function(err, fst) {
    console.log(JSON.stringify(fst, null, 4));
});

/*
{
    "qux": "file",
    "bar": {
        "baz": "file"
    },
    "quux": {
        "grault": "file",
        "corge": {
            "garply": "file"
        }
    }
}
*/

fstack.fst('./foo', function(err, fst) {
    console.log(JSON.stringify(fst, null, 4));
}, 1);

/*
{
    "bar": {},
    "quux": {},
    "qux": "file"
}
*/

fstack.fso

Alias of fstack#fst.

fstack.device(path, callback)

fstack.device(path, callback) will check the device type of path and callback with (err, mode), where mode is the determined device type of path.

Device types are file, directory, block-device, char-device, link, fifo, socket, and unknown.

/*
foo/
    bar/
        baz
    qux
*/

fstack.device('./foo', function(err, mode) {
    console.log(mode);
});

// 'directory'

fstack.mkdir(path, callback, [force])

fstack.mkdir(path, callback, [force]) will create the directory path if it does not already exist, and callback with (err). If force is specified, the directory will be created without checks. fstack#mkdir will callback with (err, made).

/*
foo/
    bar/
        baz
    qux
*/

fstack.mkdir('./foo/quux', function(err) {
    
});

/*
foo/
    bar/
        baz
    quux/
    qux
*/

fstack.mkdirp(path, callback, [force])

fstack.mkdirp(path, callback, [force]) will recursively create each directory that leads to path if any do not already exist, and callback with (err). If force is specified, directories will be created without checks. fstack#mkdirp will callback with (err).

/*
foo/
    bar/
        baz
    qux
*/

fstack.mkdirp('./foo/quux/corge', function(err) {
    
});

/*
foo/
    bar/
        baz
    quux/
        corge/
    qux
*/

fstack.copy(source, destination, callback)

fstack.copy(source, destination, callback) will recursively copy each directory and file from source to destination if source is a directory, and it will copy source to directory if source is a file. fstack#copy will create any missing directories in the process. Files in destination with the same name as files in source will be overwritten. fstack#copy will callback with (err).

/*
foo/
    bar/
        baz
    qux
*/

fstack.copy('./foo', './quux', function(err) {
    
});

/*
foo/
    bar/
        baz
    qux
quux/
    bar/
        baz
    qux
*/

fstack.move(source, destination, callback)

fstack.move(source, destination, callback) will recursively move each directory and file from source to destination if source is a directory, using fs#rename when possible. It will move source to directory if source is a file. fstack#move will create any missing directories in the process. Files in destination with the same name as files in source will be overwritten. fstack#move will callback with (err).

/*
foo/
    bar/
        baz
    qux
*/

fstack.move('./foo', './quux', function(err) {
    
});

/*
quux/
    bar/
        baz
    qux
*/

fstack.delete(path, callback)

fstack.delete(path, callback) will recursively delete each directory and file in path, if path is a directory, while it will delete path if it is a non-directory. fstack#delete will callback with (err).

/*
foo/
    bar/
        baz
    qux
*/

fstack.delete('./foo', function(err) {
    
});

/*

*/

fstack.checkFile(path, callback)

fstack.checkFile(path, callback) will check if path exists as a non-directory and callback with (err, stat), where stat is the stat of path.

fstack.checkDir(path, callback)

fstack.checkDir(path, callback) will check if path exists as a directory and callback with (err, stat), where stat is the stat of path.

fstack.json(path, callback, [explicit])

fstack.json(path, callback, [explicit]) will read the json from path if it is a file. explicit defaults to false, where it may append '.json' to the supplied path so that the file may be accessed without requiring the '.json' extension. fstack#json(path, callback, explicit) will callback with (err, json), where json is the parsed object for the file at path.

/*
test.json
    {
        "a": "b",
        "c": {
            "d": "e"
        }
    }
*/

fstack.json('./test.json', function(err, json) {
    console.log(json.c);
});

// { d: 'e' }

fstack.read(path, callback)

fstack#read behaves the same way as fs#readFile, but first performs a check to see whether the supplied file exists.

fstack.readStream(path, callback)

fstack.readStream(path, callback) will create a Readable Stream for path and callback with (err, stream).

fstack.write(path, callback)

fstack#write behaves the same way as fs#writeFile, but first performs a check to see whether the supplied file exists.

fstack.writeStream(path, callback)

fstack.writeStream(path, callback) will create a Writable Stream for path and callback with (err, stream).

fstack.append(path, callback)

fstack#append behaves the same way as fs#append, but first performs a check to see whether the supplied file exists.

rimraf

The package rimraf, which is a popular implementation of rm -rf for Node.js, actually depends on making assumptions about files and directories during the removal of entities. rimraf must choose between assuming that there is a file and assuming that there is a directory, and makes the smarter decision favoring the existence files, but this also means that for any call to rimraf where the path given contains at least one child directory, the kernel will return an error, and a new deletion request must be made. Such system calls are expensive. Instead, fstack uses its built-in entity separator to asynchronously unlink files and rmdir directories, after the children of those directories have been unlink'd or rmdir'd.