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

fs-updater

v1.0.4

Published

Incrementally update a directory based on an in-memory representation.

Downloads

482,618

Readme

node-fs-updater

Build Status Build status

Repeatedly write an in-memory directory tree to disk, with incremental updating.

Installation

This package requires Node version 6.0.0 or newer.

npm install --save fs-updater

Usage

let FSUpdater = require("fs-updater");
let { File, Directory, DirectoryIndex } = FSUpdater;

// output_dir must either be an empty directory or not exist at all
let fsUpdater = new FSUpdater('./output_dir')

Let's create the following directory structure, where -> indicates a symlink (or a copy on Windows):

output_dir
├── file -> /path/to/some/file
├── dir1/ -> /path/to/some/dir
└── dir2/
    └── another_file -> /path/to/another/file
let dir = new DirectoryIndex([
  ['file', new File('/path/to/some/file')],
  ['dir1', new Directory('/path/to/some/dir')],
  ['dir2', new DirectoryIndex([
    ['another_file', new File('/path/to/another/file')]
  ])]
]);

// Write it to ./output_dir
fsUpdater.update(dir);

Now let's create an updated similar directory structure:

.
├── file -> /path/to/some/file
└── dir1/ -> /path/to/some/dir
dir = new DirectoryIndex([
  ['file', new File('/path/to/some/file')],
  ['dir1', new Directory('/path/to/some/dir')]
]);

// Now update output_dir incrementally
fsUpdater.update(dir);

Object re-use

It is recommended that you rebuild all your File, Directory and DirectoryIndex objects from scratch each time you call fsUpdater.update. If you re-use objects, the following rules apply:

First, do not mutate the objects that you pass into FSUpdater, or their sub-objects. That is, after calling fsUpdater.update(dir), you must no longer call dir.set(...).

Second, you may re-use unchanged File, Directory and DirectoryIndex objects only if you know that the file contents they point to recursively have not changed. This is typically only the case if they point into directories that you control, and if those directories in turn contain no symlinks to outside directories under the user's control.

For example, this is always OK:

let file = new String('/the/file');
fsUpdater.update(new DirectoryIndex([
  ['file', file]
]);

// Create new File object with identical path
file = new String('/the/file');
fsUpdater.update(new DirectoryIndex([
  ['file', file]
]);

But this is only OK if the contents of /the/file have not changed between calls to .update:

let file = new String('/the/file');
fsUpdater.update(new DirectoryIndex([
  ['file', file]
]);

// Re-use the File object
fsUpdater.update(new DirectoryIndex([
  ['file', file]
]);

Reference

  • FSUpdater: An object used to repeatedly update an output directory.

    • new FSUpdater(outputPath, options): Create a new FSUpdater object. The outputPath must be an empty directory or absent.

      It is important that the FSUpdater has exclusive access to the outputPath directory. FSUpdater.prototype.update calls rimraf, which can be dangerous in the presence of symlinks if unexpected changes have been made to the outputPath directory.

      options.canSymlink (boolean): If true, use symlinks; if false, copy files and use junctions. If null (default), auto-detect.

    • FSUpdater.prototype.update(directory): Update the outputPath directory to mirror the contents of the directory object, which is either a DirectoryIndex (an in-memory directory) or a Directory (a directory on disk).

      Important note: You may re-use File objects contained in the DirectoryIndex between repeated calls to .update() only if the file contents have not changed. Similarly, you may re-use DirectoryIndex and Directory objects only if no changes have been made to the directory or any files or subdirectories recursively, including those reachable through symlinks.

  • FSUpdater.DirectoryIndex: A subclass of Map representing an in-memory directory; see the documentation there.

    DirectoryIndex objects map file names (string primitives, without paths) to DirectoryIndex, Directory or File objects.

  • FSUpdater.Directory: A directory on disk. Think of this as an in-memory symlink to a directory.

    • new Directory(path): Create a new Directory object pointing to the directory at path.

    • Directory.prototype.valueOf(): Return the path.

    • Directory.prototype.getIndexSync(): Read the physical directory and return a DirectoryIndex. The DirectoryIndex object is cached between repeated calls to getIndexSync().

  • FSUpdater.File: Represents a file on disk. Think of this as an in-memory symlink.

    • new File(path): Create a new File object pointing to the file at path.

    • File.prototype.valueOf(): Return the path.

  • FSUpdater.makeFSObject(path): Return a File or Directory object, depending on the file type on disk. This function follows symlinks.

Contributing

Clone this repo and run the tests like so:

npm install
npm test

Issues and pull requests are welcome. If you change code, be sure to re-run npm test. Oftentimes it's useful to add or update tests as well.