Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

defiler

Package Overview
Dependencies
Maintainers
1
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

defiler - npm Package Compare versions

Comparing version 0.11.0 to 0.11.1

4

CHANGELOG.md

@@ -0,1 +1,5 @@

# v0.11.1
- Close FSWatcher instances when their directories are deleted
# v0.11.0

@@ -2,0 +6,0 @@

112

dist/index.cjs.js

@@ -14,6 +14,11 @@ 'use strict';

constructor(path$$1) {
// path of file
this._path = path$$1;
// all historical paths of file
this.paths = path$$1 ? [path$$1] : [];
// stat of file
this.stat = null;
// Buffer of file contents
this._bytes = null;
// string of file contents
this._text = null;

@@ -78,14 +83,22 @@ }

super();
// directory to recursively watch the contents of
this._dir = dir;
// whether to actually watch for changes (or just walk and retrieve contents and file stats)
this._watch = watch;
// fs.watch event debounce, in milliseconds
this._debounce = debounce;
this._dirs = new Set();
// paths of all (recursive) directories -> FSWatcher instances
this._dirs = new Map();
// paths of all (recursive) files -> file stats
this._files = new Map();
// paths of (recursive) files with pending debounced events -> setTimeout timer ids
this._timeouts = new Map();
// queue of pending FSWatcher events to handle
this._queue = [];
// whether some FSWatcher event is currently already in the process of being handled
this._processing = false;
this._queue = [];
}
// recurse directroy, get stats, set up FSWatcher instances
// returns array of { file, stat }
async init() {

@@ -96,2 +109,3 @@ await this._recurse(this._dir);

// recurse a given directory
async _recurse(full) {

@@ -103,16 +117,3 @@ let path$$1 = full.slice(this._dir.length + 1);

} else if (fileStat.isDirectory()) {
if (this._watch) {
this._dirs.add(path$$1);
fs.watch(full, (_, file) => {
file = full + '/' + file;
if (this._timeouts.has(file)) clearTimeout(this._timeouts.get(file));
this._timeouts.set(
file,
setTimeout(() => {
this._timeouts.delete(file);
this._enqueue(file);
}, this._debounce),
);
});
}
if (this._watch) this._dirs.set(path$$1, fs.watch(full, this._handle.bind(this, full)));
await Promise.all((await readdir(full)).map(sub => this._recurse(full + '/' + sub)));

@@ -122,2 +123,16 @@ }

// handle FSWatcher event for given directory
_handle(dir, event, file) {
let full = dir + '/' + file;
if (this._timeouts.has(full)) clearTimeout(this._timeouts.get(full));
this._timeouts.set(
full,
setTimeout(() => {
this._timeouts.delete(full);
this._enqueue(full);
}, this._debounce),
);
}
// add an FSWatcher event to the queue, and handle queued events
async _enqueue(full) {

@@ -128,3 +143,3 @@ this._queue.push(full);

while (this._queue.length) {
full = this._queue.shift();
let full = this._queue.shift();
let path$$1 = full.slice(this._dir.length + 1);

@@ -134,5 +149,7 @@ try {

if (fileStat.isFile()) {
// note the new/changed file
this._files.set(path$$1, fileStat);
this.emit('', { event: '+', path: path$$1, stat: fileStat });
} else if (fileStat.isDirectory() && !this._dirs.has(path$$1)) {
// note the new directory: start watching it, and report any files in it
await this._recurse(full);

@@ -146,7 +163,15 @@ for (let [newPath, fileStat] of this._files.entries()) {

} catch (e) {
// probably this was a deleted file/directory
if (this._files.has(path$$1)) {
// note the deleted file
this._files.delete(path$$1);
this.emit('', { event: '-', path: path$$1 });
} else if (this._dirs.has(path$$1)) {
this._dirs.delete(path$$1);
// note the deleted directory: stop watching it, and report any files that were in it
for (let old of this._dirs.keys()) {
if (old === path$$1 || old.startsWith(path$$1 + '/')) {
this._dirs.get(old).close();
this._dirs.delete(old);
}
}
for (let old of this._files.keys()) {

@@ -158,3 +183,2 @@ if (old.startsWith(path$$1 + '/')) {

}
for (let old of this._dirs.keys()) if (old.startsWith(path$$1 + '/')) this._dirs.delete(old);
}

@@ -176,3 +200,3 @@ }

this._status = null;
// all registered watchers (one per directory)
// all registered Watcher instances (one per directory)
this._watchers = [];

@@ -183,10 +207,6 @@ // all registered transforms

this._generators = new Map();
// how many promises we're currently waiting to resolve as part of the first exec wave
this._count = 0;
// resolve main exec promise
this._res = null;
// reject main exec promise
this._rej = null;
// original paths of all files currently undergoing some transform
this._transforming = new Set();
// { count, resolve, reject } object for main promise for the first exec wave
this._done = { count: 0, resolve: null, reject: null };
// original paths of all files currently undergoing some transform/generator
this._pending = new Set();
// original paths -> number of other files they're currently waiting on to exist

@@ -198,5 +218,5 @@ this._waiting = new Map();

this._dependents = new Map();
// queue of pending watcher events to handle
// queue of pending Watcher events to handle
this._queue = [];
// where some watcher event is currently already in the process of being handled
// whether some Watcher event is currently already in the process of being handled
this._processing = false;

@@ -225,3 +245,3 @@ }

// register one or more directories/watchers
// register one or more directories/Watchers
dir(...dirs) {

@@ -260,6 +280,6 @@ this._checkBeforeExec('dir');

let promise = new Promise((res, rej) => {
this._res = res;
this._rej = rej;
this._done.resolve = res;
this._done.reject = rej;
});
// init all watchers; note that all files have pending transforms
// init all Watcher instances; note that all files have pending transforms
let files = [];

@@ -274,7 +294,7 @@ await Promise.all(

this._origFiles.set(path$$1, null);
this._transforming.add(path$$1);
this._pending.add(path$$1);
}
}),
);
for (let path$$1 of this._generators.keys()) this._transforming.add(path$$1);
for (let path$$1 of this._generators.keys()) this._pending.add(path$$1);
// process each physical file

@@ -329,4 +349,4 @@ for (let { dir, path: path$$1, stat: stat$$1, read } of files) {

if (!this._status) {
this._count++;
promise.then(() => --this._count || this._res(), this._rej);
this._done.count++;
promise.then(() => --this._done.count || this._done.resolve(), this._done.reject);
}

@@ -336,3 +356,3 @@ return promise

// add a watcher event from the queue, and handle queued events
// add a Watcher event to the queue, and handle queued events
async _enqueue(event) {

@@ -379,3 +399,3 @@ this._queue.push(event);

let { path: path$$1 } = file;
this._transforming.add(path$$1);
this._pending.add(path$$1);
try {

@@ -393,7 +413,7 @@ for (let transform of this._transforms) {

}
this._transforming.delete(path$$1);
if (!this._status && [...this._transforming].every(path$$1 => this._waiting.get(path$$1))) {
// all pending transforming files are currently waiting for one or more other files to exist
this._pending.delete(path$$1);
if (!this._status && [...this._pending].every(path$$1 => this._waiting.get(path$$1))) {
// all pending files are currently waiting for one or more other files to exist
// break deadlock: assume all files that have not appeared yet will never do so
for (let path$$1 of this._available.keys()) if (!this._transforming.has(path$$1)) this._found(path$$1);
for (let path$$1 of this._available.keys()) if (!this._pending.has(path$$1)) this._found(path$$1);
}

@@ -400,0 +420,0 @@ }

@@ -8,6 +8,11 @@ import { readdir, readFile, stat, watch } from 'fs';

constructor(path) {
// path of file
this._path = path;
// all historical paths of file
this.paths = path ? [path] : [];
// stat of file
this.stat = null;
// Buffer of file contents
this._bytes = null;
// string of file contents
this._text = null;

@@ -72,14 +77,22 @@ }

super();
// directory to recursively watch the contents of
this._dir = dir;
// whether to actually watch for changes (or just walk and retrieve contents and file stats)
this._watch = watch$$1;
// fs.watch event debounce, in milliseconds
this._debounce = debounce;
this._dirs = new Set();
// paths of all (recursive) directories -> FSWatcher instances
this._dirs = new Map();
// paths of all (recursive) files -> file stats
this._files = new Map();
// paths of (recursive) files with pending debounced events -> setTimeout timer ids
this._timeouts = new Map();
// queue of pending FSWatcher events to handle
this._queue = [];
// whether some FSWatcher event is currently already in the process of being handled
this._processing = false;
this._queue = [];
}
// recurse directroy, get stats, set up FSWatcher instances
// returns array of { file, stat }
async init() {

@@ -90,2 +103,3 @@ await this._recurse(this._dir);

// recurse a given directory
async _recurse(full) {

@@ -97,16 +111,3 @@ let path = full.slice(this._dir.length + 1);

} else if (fileStat.isDirectory()) {
if (this._watch) {
this._dirs.add(path);
watch(full, (_, file) => {
file = full + '/' + file;
if (this._timeouts.has(file)) clearTimeout(this._timeouts.get(file));
this._timeouts.set(
file,
setTimeout(() => {
this._timeouts.delete(file);
this._enqueue(file);
}, this._debounce),
);
});
}
if (this._watch) this._dirs.set(path, watch(full, this._handle.bind(this, full)));
await Promise.all((await readdir$1(full)).map(sub => this._recurse(full + '/' + sub)));

@@ -116,2 +117,16 @@ }

// handle FSWatcher event for given directory
_handle(dir, event, file) {
let full = dir + '/' + file;
if (this._timeouts.has(full)) clearTimeout(this._timeouts.get(full));
this._timeouts.set(
full,
setTimeout(() => {
this._timeouts.delete(full);
this._enqueue(full);
}, this._debounce),
);
}
// add an FSWatcher event to the queue, and handle queued events
async _enqueue(full) {

@@ -122,3 +137,3 @@ this._queue.push(full);

while (this._queue.length) {
full = this._queue.shift();
let full = this._queue.shift();
let path = full.slice(this._dir.length + 1);

@@ -128,5 +143,7 @@ try {

if (fileStat.isFile()) {
// note the new/changed file
this._files.set(path, fileStat);
this.emit('', { event: '+', path, stat: fileStat });
} else if (fileStat.isDirectory() && !this._dirs.has(path)) {
// note the new directory: start watching it, and report any files in it
await this._recurse(full);

@@ -140,7 +157,15 @@ for (let [newPath, fileStat] of this._files.entries()) {

} catch (e) {
// probably this was a deleted file/directory
if (this._files.has(path)) {
// note the deleted file
this._files.delete(path);
this.emit('', { event: '-', path });
} else if (this._dirs.has(path)) {
this._dirs.delete(path);
// note the deleted directory: stop watching it, and report any files that were in it
for (let old of this._dirs.keys()) {
if (old === path || old.startsWith(path + '/')) {
this._dirs.get(old).close();
this._dirs.delete(old);
}
}
for (let old of this._files.keys()) {

@@ -152,3 +177,2 @@ if (old.startsWith(path + '/')) {

}
for (let old of this._dirs.keys()) if (old.startsWith(path + '/')) this._dirs.delete(old);
}

@@ -170,3 +194,3 @@ }

this._status = null;
// all registered watchers (one per directory)
// all registered Watcher instances (one per directory)
this._watchers = [];

@@ -177,10 +201,6 @@ // all registered transforms

this._generators = new Map();
// how many promises we're currently waiting to resolve as part of the first exec wave
this._count = 0;
// resolve main exec promise
this._res = null;
// reject main exec promise
this._rej = null;
// original paths of all files currently undergoing some transform
this._transforming = new Set();
// { count, resolve, reject } object for main promise for the first exec wave
this._done = { count: 0, resolve: null, reject: null };
// original paths of all files currently undergoing some transform/generator
this._pending = new Set();
// original paths -> number of other files they're currently waiting on to exist

@@ -192,5 +212,5 @@ this._waiting = new Map();

this._dependents = new Map();
// queue of pending watcher events to handle
// queue of pending Watcher events to handle
this._queue = [];
// where some watcher event is currently already in the process of being handled
// whether some Watcher event is currently already in the process of being handled
this._processing = false;

@@ -219,3 +239,3 @@ }

// register one or more directories/watchers
// register one or more directories/Watchers
dir(...dirs) {

@@ -254,6 +274,6 @@ this._checkBeforeExec('dir');

let promise = new Promise((res, rej) => {
this._res = res;
this._rej = rej;
this._done.resolve = res;
this._done.reject = rej;
});
// init all watchers; note that all files have pending transforms
// init all Watcher instances; note that all files have pending transforms
let files = [];

@@ -268,7 +288,7 @@ await Promise.all(

this._origFiles.set(path, null);
this._transforming.add(path);
this._pending.add(path);
}
}),
);
for (let path of this._generators.keys()) this._transforming.add(path);
for (let path of this._generators.keys()) this._pending.add(path);
// process each physical file

@@ -323,4 +343,4 @@ for (let { dir, path, stat: stat$$1, read } of files) {

if (!this._status) {
this._count++;
promise.then(() => --this._count || this._res(), this._rej);
this._done.count++;
promise.then(() => --this._done.count || this._done.resolve(), this._done.reject);
}

@@ -330,3 +350,3 @@ return promise

// add a watcher event from the queue, and handle queued events
// add a Watcher event to the queue, and handle queued events
async _enqueue(event) {

@@ -373,3 +393,3 @@ this._queue.push(event);

let { path } = file;
this._transforming.add(path);
this._pending.add(path);
try {

@@ -387,7 +407,7 @@ for (let transform of this._transforms) {

}
this._transforming.delete(path);
if (!this._status && [...this._transforming].every(path => this._waiting.get(path))) {
// all pending transforming files are currently waiting for one or more other files to exist
this._pending.delete(path);
if (!this._status && [...this._pending].every(path => this._waiting.get(path))) {
// all pending files are currently waiting for one or more other files to exist
// break deadlock: assume all files that have not appeared yet will never do so
for (let path of this._available.keys()) if (!this._transforming.has(path)) this._found(path);
for (let path of this._available.keys()) if (!this._pending.has(path)) this._found(path);
}

@@ -394,0 +414,0 @@ }

{
"name": "defiler",
"version": "0.11.0",
"version": "0.11.1",
"description": "A small, strange building block",

@@ -5,0 +5,0 @@ "keywords": ["build", "framework", "async", "watch"],

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc