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

watchpack

v2.4.2

Published

Wrapper library for directory and file watching.

Downloads

119,140,871

Readme

watchpack

Wrapper library for directory and file watching.

Test Codecov Downloads

Concept

watchpack high level API doesn't map directly to watchers. Instead a three level architecture ensures that for each directory only a single watcher exists.

  • The high level API requests DirectoryWatchers from a WatcherManager, which ensures that only a single DirectoryWatcher per directory is created.
  • A user-faced Watcher can be obtained from a DirectoryWatcher and provides a filtered view on the DirectoryWatcher.
  • Reference-counting is used on the DirectoryWatcher and Watcher to decide when to close them.
  • The real watchers are created by the DirectoryWatcher.
  • Files are never watched directly. This should keep the watcher count low.
  • Watching can be started in the past. This way watching can start after file reading.
  • Symlinks are not followed, instead the symlink is watched.

API

var Watchpack = require("watchpack");

var wp = new Watchpack({
	// options:
	aggregateTimeout: 1000,
	// fire "aggregated" event when after a change for 1000ms no additional change occurred
	// aggregated defaults to undefined, which doesn't fire an "aggregated" event

	poll: true,
	// poll: true - use polling with the default interval
	// poll: 10000 - use polling with an interval of 10s
	// poll defaults to undefined, which prefer native watching methods
	// Note: enable polling when watching on a network path
	// When WATCHPACK_POLLING environment variable is set it will override this option

	followSymlinks: true,
	// true: follows symlinks and watches symlinks and real files
	//   (This makes sense when symlinks has not been resolved yet, comes with a performance hit)
	// false (default): watches only specified item they may be real files or symlinks
	//   (This makes sense when symlinks has already been resolved)

	ignored: "**/.git"
	// ignored: "string" - a glob pattern for files or folders that should not be watched
	// ignored: ["string", "string"] - multiple glob patterns that should be ignored
	// ignored: /regexp/ - a regular expression for files or folders that should not be watched
	// ignored: (entry) => boolean - an arbitrary function which must return truthy to ignore an entry
	// For all cases expect the arbitrary function the path will have path separator normalized to '/'.
	// All subdirectories are ignored too
});

// Watchpack.prototype.watch({
//   files: Iterable<string>,
//   directories: Iterable<string>,
//   missing: Iterable<string>,
//   startTime?: number
// })
wp.watch({
	files: listOfFiles,
	directories: listOfDirectories,
	missing: listOfNotExistingItems,
	startTime: Date.now() - 10000
});
// starts watching these files and directories
// calling this again will override the files and directories
// files: can be files or directories, for files: content and existence changes are tracked
//        for directories: only existence and timestamp changes are tracked
// directories: only directories, directory content (and content of children, ...) and
//              existence changes are tracked.
//              assumed to exist, when directory is not found without further information a remove event is emitted
// missing: can be files or directorees,
//          only existence changes are tracked
//          expected to not exist, no remove event is emitted when not found initially
// files and directories are assumed to exist, when they are not found without further information a remove event is emitted
// missing is assumed to not exist and no remove event is emitted

wp.on("change", function(filePath, mtime, explanation) {
	// filePath: the changed file
	// mtime: last modified time for the changed file
	// explanation: textual information how this change was detected
});

wp.on("remove", function(filePath, explanation) {
	// filePath: the removed file or directory
	// explanation: textual information how this change was detected
});

wp.on("aggregated", function(changes, removals) {
	// changes: a Set of all changed files
	// removals: a Set of all removed files
	// watchpack gives up ownership on these Sets.
});

// Watchpack.prototype.pause()
wp.pause();
// stops emitting events, but keeps watchers open
// next "watch" call can reuse the watchers
// The watcher will keep aggregating events
// which can be received with getAggregated()

// Watchpack.prototype.close()
wp.close();
// stops emitting events and closes all watchers

// Watchpack.prototype.getAggregated(): { changes: Set<string>, removals: Set<string> }
const { changes, removals } = wp.getAggregated();
// returns the current aggregated info and removes that from the watcher
// The next aggregated event won't include that info and will only emitted
// when futher changes happen
// Can also be used when paused.

// Watchpack.prototype.collectTimeInfoEntries(fileInfoEntries: Map<string, Entry>, directoryInfoEntries: Map<string, Entry>)
wp.collectTimeInfoEntries(fileInfoEntries, directoryInfoEntries);
// collects time info objects for all known files and directories
// this include info from files not directly watched
// key: absolute path, value: object with { safeTime, timestamp }
// safeTime: a point in time at which it is safe to say all changes happened before that
// timestamp: only for files, the mtime timestamp of the file

// Watchpack.prototype.getTimeInfoEntries()
var fileTimes = wp.getTimeInfoEntries();
// returns a Map with all known time info objects for files and directories
// similar to collectTimeInfoEntries but returns a single map with all entries

// (deprecated)
// Watchpack.prototype.getTimes()
var fileTimes = wp.getTimes();
// returns an object with all known change times for files
// this include timestamps from files not directly watched
// key: absolute path, value: timestamp as number