Comparing version 0.12.0 to 0.12.1
@@ -0,1 +1,7 @@ | ||
# v0.12.1 | ||
- Document `file.stats` (formerly `file.stat`, shhh) | ||
- Wait for all `defiler.add`ed files to settle before proceeding with handling the next watch event | ||
- Prevent mutations to `file.paths` from making their way back into the original copy of the `File` | ||
# v0.12.0 | ||
@@ -2,0 +8,0 @@ |
@@ -25,4 +25,4 @@ 'use strict'; | ||
this.paths = path$$1 ? [path$$1] : []; | ||
// stat of file | ||
this.stat = null; | ||
// stats of file | ||
this.stats = null; | ||
// encoding | ||
@@ -129,2 +129,22 @@ this[_enc] = 'utf8'; | ||
let { _count, _resolve, _reject } = symbols; | ||
class Waiter { | ||
// initialize/reset, and set a promise property that can be awaited | ||
init() { | ||
this[_count] = 0; | ||
this.promise = new Promise((res, rej) => { | ||
this[_resolve] = res; | ||
this[_reject] = rej; | ||
}); | ||
} | ||
// add another promise that must be resolved before the main promise resolves | ||
add(promise) { | ||
this[_count]++; | ||
promise.then(() => --this[_count] || this[_resolve](), this[_reject]); | ||
return promise | ||
} | ||
} | ||
let { | ||
@@ -166,6 +186,6 @@ _dir: _dir$1, | ||
// recurse directroy, get stats, set up FSWatcher instances | ||
// returns array of { file, stat } | ||
// returns array of { file, stats } | ||
async init() { | ||
await this[_recurse](this[_dir$1]); | ||
return [...this[_files].entries()].map(([path$$1, stat$$1]) => ({ path: path$$1, stat: stat$$1 })) | ||
return [...this[_files].entries()].map(([path$$1, stats]) => ({ path: path$$1, stats })) | ||
} | ||
@@ -176,6 +196,6 @@ | ||
let path$$1 = full.slice(this[_dir$1].length + 1); | ||
let fileStat = await stat(full); | ||
if (fileStat.isFile()) { | ||
this[_files].set(path$$1, fileStat); | ||
} else if (fileStat.isDirectory()) { | ||
let stats = await stat(full); | ||
if (stats.isFile()) { | ||
this[_files].set(path$$1, stats); | ||
} else if (stats.isDirectory()) { | ||
if (this[_watch]) this[_dirs].set(path$$1, fs.watch(full, this[_handle].bind(this, full))); | ||
@@ -208,13 +228,13 @@ await Promise.all((await readdir(full)).map(sub => this[_recurse](full + '/' + sub))); | ||
try { | ||
let fileStat = await stat(full); | ||
if (fileStat.isFile()) { | ||
let stats = await stat(full); | ||
if (stats.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)) { | ||
this[_files].set(path$$1, stats); | ||
this.emit('', { event: '+', path: path$$1, stats }); | ||
} else if (stats.isDirectory() && !this[_dirs].has(path$$1)) { | ||
// note the new directory: start watching it, and report any files in it | ||
await this[_recurse](full); | ||
for (let [newPath, fileStat] of this[_files].entries()) { | ||
for (let [newPath, stats] of this[_files].entries()) { | ||
if (newPath.startsWith(path$$1 + '/')) { | ||
this.emit('', { event: '+', path: newPath, stat: fileStat }); | ||
this.emit('', { event: '+', path: newPath, stats }); | ||
} | ||
@@ -251,5 +271,3 @@ } | ||
let { | ||
_paths, | ||
_origFiles, | ||
_files: _files$1, | ||
_status, | ||
@@ -259,3 +277,3 @@ _dir: _dir$2, | ||
_generators, | ||
_done, | ||
_waiter, | ||
_pending, | ||
@@ -267,3 +285,2 @@ _waiting, | ||
_processing: _processing$1, | ||
_wait, | ||
_enqueue: _enqueue$1, | ||
@@ -305,7 +322,7 @@ _processPhysicalFile, | ||
// set of original paths for all physical files | ||
this[_paths] = new Set(); | ||
this.paths = new Set(); | ||
// original paths -> original files for all physical files | ||
this[_origFiles] = new Map(); | ||
// original paths -> transformed files for all physical and virtual files | ||
this[_files$1] = new Map(); | ||
this.files = new Map(); | ||
// null = exec not called; false = exec pending; true = exec finished | ||
@@ -321,4 +338,4 @@ this[_status] = null; | ||
for (let generator of generators) this[_generators].set(Symbol(), generator); | ||
// { count, resolve, reject } object for main promise for the first exec wave | ||
this[_done] = { count: 0, resolve: null, reject: null }; | ||
// Waiter instance, to help wait for all promises in the current wave to resolve | ||
this[_waiter] = new Waiter(); | ||
// original paths of all files currently undergoing transformation and symbols of all generators running | ||
@@ -338,14 +355,2 @@ this[_pending] = new Set(); | ||
// read-only getters | ||
get files() { | ||
if (this[_status] === null) throw new Error('defiler.files: cannot access before calling exec') | ||
return this[_files$1] | ||
} | ||
get paths() { | ||
if (this[_status] === null) throw new Error('defiler.paths: cannot access before calling exec') | ||
return this[_paths] | ||
} | ||
// exec | ||
@@ -357,6 +362,3 @@ | ||
this[_processing$1] = true; | ||
let promise = new Promise((res, rej) => { | ||
this[_done].resolve = res; | ||
this[_done].reject = rej; | ||
}); | ||
this[_waiter].init(); | ||
// init the Watcher instance | ||
@@ -368,3 +370,3 @@ let { watcher, watch } = this[_dir$2]; | ||
for (let { path: path$$1 } of files) { | ||
this[_paths].add(path$$1); | ||
this.paths.add(path$$1); | ||
this[_pending].add(path$$1); | ||
@@ -374,7 +376,7 @@ } | ||
// process each physical file | ||
for (let { path: path$$1, stat: stat$$1 } of files) this[_wait](this[_processPhysicalFile](path$$1, stat$$1)); | ||
for (let { path: path$$1, stats } of files) this[_waiter].add(this[_processPhysicalFile](path$$1, stats)); | ||
// process each generator | ||
for (let symbol of this[_generators].keys()) this[_wait](this[_processGenerator](symbol)); | ||
for (let symbol of this[_generators].keys()) this[_waiter].add(this[_processGenerator](symbol)); | ||
// wait and finish up | ||
await promise; | ||
await this[_waiter].promise; | ||
this[_status] = true; | ||
@@ -392,4 +394,4 @@ this[_processing$1] = false; | ||
if (!(file instanceof File)) file = Object.assign(new File(), file); | ||
await this[_wait](this[_transformFile](file)); | ||
this[_files$1].set(path$$1, file); | ||
await this[_waiter].add(this[_transformFile](file)); | ||
this.files.set(path$$1, file); | ||
this.emit('file', { defiler: this, file }); | ||
@@ -416,11 +418,2 @@ this[_found](path$$1); | ||
// add another promise that must resolve before the initial exec wave can finish | ||
[_wait](promise) { | ||
if (!this[_status]) { | ||
this[_done].count++; | ||
promise.then(() => --this[_done].count || this[_done].resolve(), this[_done].reject); | ||
} | ||
return promise | ||
} | ||
// add a Watcher event to the queue, and handle queued events | ||
@@ -432,10 +425,12 @@ async [_enqueue$1](event) { | ||
while (this[_queue$1].length) { | ||
let { event, path: path$$1, stat: stat$$1 } = this[_queue$1].shift(); | ||
let { event, path: path$$1, stats } = this[_queue$1].shift(); | ||
if (event === '+') { | ||
await this[_processPhysicalFile](path$$1, stat$$1); | ||
this[_waiter].init(); | ||
this[_waiter].add(this[_processPhysicalFile](path$$1, stats)); | ||
await this[_waiter].promise; | ||
} else if (event === '-') { | ||
let file = this[_files$1].get(path$$1); | ||
this[_paths].delete(path$$1); | ||
let file = this.files.get(path$$1); | ||
this.paths.delete(path$$1); | ||
this[_origFiles].delete(path$$1); | ||
this[_files$1].delete(path$$1); | ||
this.files.delete(path$$1); | ||
this.emit('deleted', { defiler: this, file }); | ||
@@ -449,7 +444,7 @@ this[_processDependents](path$$1); | ||
// create a file object for a physical file and process it | ||
async [_processPhysicalFile](path$$1, stat$$1) { | ||
async [_processPhysicalFile](path$$1, stats) { | ||
let { dir, read, enc } = this[_dir$2]; | ||
let file = Object.assign(new File(), { path: path$$1, stat: stat$$1, enc }); | ||
let file = Object.assign(new File(), { path: path$$1, stats, enc }); | ||
if (read) file.bytes = await readFile(dir + '/' + path$$1); | ||
this[_paths].add(path$$1); | ||
this.paths.add(path$$1); | ||
this[_origFiles].set(path$$1, file); | ||
@@ -462,5 +457,5 @@ this.emit('read', { defiler: this, file }); | ||
async [_processFile](origFile) { | ||
let file = Object.assign(new File(), origFile); | ||
let file = Object.assign(new File(), origFile, { paths: [origFile.path] }); | ||
await this[_transformFile](file); | ||
this[_files$1].set(origFile.path, file); | ||
this.files.set(origFile.path, file); | ||
this.emit('file', { defiler: this, file }); | ||
@@ -508,3 +503,3 @@ this[_found](origFile.path); | ||
this.depend(dependent, path$$1); | ||
if (!this[_status] && !this[_files$1].has(path$$1)) { | ||
if (!this[_status] && !this.files.has(path$$1)) { | ||
this[_waiting].set(dependent, (this[_waiting].get(dependent) || 0) + 1); | ||
@@ -521,3 +516,3 @@ if (this[_available].has(path$$1)) { | ||
} | ||
return this[_files$1].get(path$$1) | ||
return this.files.get(path$$1) | ||
} | ||
@@ -524,0 +519,0 @@ |
@@ -19,4 +19,4 @@ import { readdir, readFile, stat, watch } from 'fs'; | ||
this.paths = path ? [path] : []; | ||
// stat of file | ||
this.stat = null; | ||
// stats of file | ||
this.stats = null; | ||
// encoding | ||
@@ -123,2 +123,22 @@ this[_enc] = 'utf8'; | ||
let { _count, _resolve, _reject } = symbols; | ||
class Waiter { | ||
// initialize/reset, and set a promise property that can be awaited | ||
init() { | ||
this[_count] = 0; | ||
this.promise = new Promise((res, rej) => { | ||
this[_resolve] = res; | ||
this[_reject] = rej; | ||
}); | ||
} | ||
// add another promise that must be resolved before the main promise resolves | ||
add(promise) { | ||
this[_count]++; | ||
promise.then(() => --this[_count] || this[_resolve](), this[_reject]); | ||
return promise | ||
} | ||
} | ||
let { | ||
@@ -160,6 +180,6 @@ _dir: _dir$1, | ||
// recurse directroy, get stats, set up FSWatcher instances | ||
// returns array of { file, stat } | ||
// returns array of { file, stats } | ||
async init() { | ||
await this[_recurse](this[_dir$1]); | ||
return [...this[_files].entries()].map(([path, stat$$1]) => ({ path, stat: stat$$1 })) | ||
return [...this[_files].entries()].map(([path, stats]) => ({ path, stats })) | ||
} | ||
@@ -170,6 +190,6 @@ | ||
let path = full.slice(this[_dir$1].length + 1); | ||
let fileStat = await stat$1(full); | ||
if (fileStat.isFile()) { | ||
this[_files].set(path, fileStat); | ||
} else if (fileStat.isDirectory()) { | ||
let stats = await stat$1(full); | ||
if (stats.isFile()) { | ||
this[_files].set(path, stats); | ||
} else if (stats.isDirectory()) { | ||
if (this[_watch]) this[_dirs].set(path, watch(full, this[_handle].bind(this, full))); | ||
@@ -202,13 +222,13 @@ await Promise.all((await readdir$1(full)).map(sub => this[_recurse](full + '/' + sub))); | ||
try { | ||
let fileStat = await stat$1(full); | ||
if (fileStat.isFile()) { | ||
let stats = await stat$1(full); | ||
if (stats.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)) { | ||
this[_files].set(path, stats); | ||
this.emit('', { event: '+', path, stats }); | ||
} else if (stats.isDirectory() && !this[_dirs].has(path)) { | ||
// note the new directory: start watching it, and report any files in it | ||
await this[_recurse](full); | ||
for (let [newPath, fileStat] of this[_files].entries()) { | ||
for (let [newPath, stats] of this[_files].entries()) { | ||
if (newPath.startsWith(path + '/')) { | ||
this.emit('', { event: '+', path: newPath, stat: fileStat }); | ||
this.emit('', { event: '+', path: newPath, stats }); | ||
} | ||
@@ -245,5 +265,3 @@ } | ||
let { | ||
_paths, | ||
_origFiles, | ||
_files: _files$1, | ||
_status, | ||
@@ -253,3 +271,3 @@ _dir: _dir$2, | ||
_generators, | ||
_done, | ||
_waiter, | ||
_pending, | ||
@@ -261,3 +279,2 @@ _waiting, | ||
_processing: _processing$1, | ||
_wait, | ||
_enqueue: _enqueue$1, | ||
@@ -299,7 +316,7 @@ _processPhysicalFile, | ||
// set of original paths for all physical files | ||
this[_paths] = new Set(); | ||
this.paths = new Set(); | ||
// original paths -> original files for all physical files | ||
this[_origFiles] = new Map(); | ||
// original paths -> transformed files for all physical and virtual files | ||
this[_files$1] = new Map(); | ||
this.files = new Map(); | ||
// null = exec not called; false = exec pending; true = exec finished | ||
@@ -315,4 +332,4 @@ this[_status] = null; | ||
for (let generator of generators) this[_generators].set(Symbol(), generator); | ||
// { count, resolve, reject } object for main promise for the first exec wave | ||
this[_done] = { count: 0, resolve: null, reject: null }; | ||
// Waiter instance, to help wait for all promises in the current wave to resolve | ||
this[_waiter] = new Waiter(); | ||
// original paths of all files currently undergoing transformation and symbols of all generators running | ||
@@ -332,14 +349,2 @@ this[_pending] = new Set(); | ||
// read-only getters | ||
get files() { | ||
if (this[_status] === null) throw new Error('defiler.files: cannot access before calling exec') | ||
return this[_files$1] | ||
} | ||
get paths() { | ||
if (this[_status] === null) throw new Error('defiler.paths: cannot access before calling exec') | ||
return this[_paths] | ||
} | ||
// exec | ||
@@ -351,6 +356,3 @@ | ||
this[_processing$1] = true; | ||
let promise = new Promise((res, rej) => { | ||
this[_done].resolve = res; | ||
this[_done].reject = rej; | ||
}); | ||
this[_waiter].init(); | ||
// init the Watcher instance | ||
@@ -362,3 +364,3 @@ let { watcher, watch: watch$$1 } = this[_dir$2]; | ||
for (let { path } of files) { | ||
this[_paths].add(path); | ||
this.paths.add(path); | ||
this[_pending].add(path); | ||
@@ -368,7 +370,7 @@ } | ||
// process each physical file | ||
for (let { path, stat: stat$$1 } of files) this[_wait](this[_processPhysicalFile](path, stat$$1)); | ||
for (let { path, stats } of files) this[_waiter].add(this[_processPhysicalFile](path, stats)); | ||
// process each generator | ||
for (let symbol of this[_generators].keys()) this[_wait](this[_processGenerator](symbol)); | ||
for (let symbol of this[_generators].keys()) this[_waiter].add(this[_processGenerator](symbol)); | ||
// wait and finish up | ||
await promise; | ||
await this[_waiter].promise; | ||
this[_status] = true; | ||
@@ -386,4 +388,4 @@ this[_processing$1] = false; | ||
if (!(file instanceof File)) file = Object.assign(new File(), file); | ||
await this[_wait](this[_transformFile](file)); | ||
this[_files$1].set(path, file); | ||
await this[_waiter].add(this[_transformFile](file)); | ||
this.files.set(path, file); | ||
this.emit('file', { defiler: this, file }); | ||
@@ -410,11 +412,2 @@ this[_found](path); | ||
// add another promise that must resolve before the initial exec wave can finish | ||
[_wait](promise) { | ||
if (!this[_status]) { | ||
this[_done].count++; | ||
promise.then(() => --this[_done].count || this[_done].resolve(), this[_done].reject); | ||
} | ||
return promise | ||
} | ||
// add a Watcher event to the queue, and handle queued events | ||
@@ -426,10 +419,12 @@ async [_enqueue$1](event) { | ||
while (this[_queue$1].length) { | ||
let { event, path, stat: stat$$1 } = this[_queue$1].shift(); | ||
let { event, path, stats } = this[_queue$1].shift(); | ||
if (event === '+') { | ||
await this[_processPhysicalFile](path, stat$$1); | ||
this[_waiter].init(); | ||
this[_waiter].add(this[_processPhysicalFile](path, stats)); | ||
await this[_waiter].promise; | ||
} else if (event === '-') { | ||
let file = this[_files$1].get(path); | ||
this[_paths].delete(path); | ||
let file = this.files.get(path); | ||
this.paths.delete(path); | ||
this[_origFiles].delete(path); | ||
this[_files$1].delete(path); | ||
this.files.delete(path); | ||
this.emit('deleted', { defiler: this, file }); | ||
@@ -443,7 +438,7 @@ this[_processDependents](path); | ||
// create a file object for a physical file and process it | ||
async [_processPhysicalFile](path, stat$$1) { | ||
async [_processPhysicalFile](path, stats) { | ||
let { dir, read, enc } = this[_dir$2]; | ||
let file = Object.assign(new File(), { path, stat: stat$$1, enc }); | ||
let file = Object.assign(new File(), { path, stats, enc }); | ||
if (read) file.bytes = await readFile$1(dir + '/' + path); | ||
this[_paths].add(path); | ||
this.paths.add(path); | ||
this[_origFiles].set(path, file); | ||
@@ -456,5 +451,5 @@ this.emit('read', { defiler: this, file }); | ||
async [_processFile](origFile) { | ||
let file = Object.assign(new File(), origFile); | ||
let file = Object.assign(new File(), origFile, { paths: [origFile.path] }); | ||
await this[_transformFile](file); | ||
this[_files$1].set(origFile.path, file); | ||
this.files.set(origFile.path, file); | ||
this.emit('file', { defiler: this, file }); | ||
@@ -502,3 +497,3 @@ this[_found](origFile.path); | ||
this.depend(dependent, path); | ||
if (!this[_status] && !this[_files$1].has(path)) { | ||
if (!this[_status] && !this.files.has(path)) { | ||
this[_waiting].set(dependent, (this[_waiting].get(dependent) || 0) + 1); | ||
@@ -515,3 +510,3 @@ if (this[_available].has(path)) { | ||
} | ||
return this[_files$1].get(path) | ||
return this.files.get(path) | ||
} | ||
@@ -518,0 +513,0 @@ |
{ | ||
"name": "defiler", | ||
"version": "0.12.0", | ||
"version": "0.12.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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
109749
960