Comparing version 0.11.2 to 0.12.0
@@ -0,1 +1,7 @@ | ||
# v0.12.0 | ||
- Simplify the API yet again - see docs | ||
- Add new [guide](GUIDE.md#readme) to the docs | ||
- Add more typechecking | ||
# v0.11.2 | ||
@@ -2,0 +8,0 @@ |
@@ -246,7 +246,8 @@ 'use strict'; | ||
let { | ||
_paths, | ||
_origFiles, | ||
_files: _files$1, | ||
_status, | ||
_watchers, | ||
_transforms, | ||
_dir: _dir$2, | ||
_transform, | ||
_generators, | ||
@@ -260,4 +261,2 @@ _done, | ||
_processing: _processing$1, | ||
_checkBeforeExec, | ||
_checkAfterExec, | ||
_wait, | ||
@@ -268,3 +267,3 @@ _enqueue: _enqueue$1, | ||
_transformFile, | ||
_handleGeneratedFile, | ||
_processGenerator, | ||
_get, | ||
@@ -276,19 +275,45 @@ _processDependents, | ||
class Defiler extends EventEmitter { | ||
constructor() { | ||
constructor({ | ||
dir, | ||
read = true, | ||
enc = 'utf8', | ||
watch = true, | ||
debounce = 10, | ||
transform, | ||
generators = [], | ||
}) { | ||
if (typeof dir !== 'string') throw new TypeError('defiler: dir must be a string') | ||
if (typeof read !== 'boolean') throw new TypeError('defiler: read must be a boolean') | ||
if (!Buffer.isEncoding(enc)) throw new TypeError('defiler: enc must be a supported encoding') | ||
if (typeof watch !== 'boolean') throw new TypeError('defiler: watch must be a boolean') | ||
if (typeof debounce !== 'number') throw new TypeError('defiler: debounce must be a number') | ||
if (typeof transform !== 'function') { | ||
throw new TypeError('defiler: transform must be a function') | ||
} | ||
if ( | ||
!generators[Symbol.iterator] || | ||
[...generators].some(generator => typeof generator !== 'function') | ||
) { | ||
throw new TypeError('defiler: generators must be a collection of functions') | ||
} | ||
super(); | ||
// set of original paths for all physical files | ||
this[_paths] = new Set(); | ||
// original paths -> original files for all physical files | ||
this[_origFiles] = new Map(); | ||
// original paths -> transformed files for all physical/generated/etc. files | ||
// original paths -> transformed files for all physical and virtual files | ||
this[_files$1] = new Map(); | ||
// null = exec not called; false = exec pending; true = exec finished | ||
this[_status] = null; | ||
// all registered Watcher instances (one per directory) | ||
this[_watchers] = []; | ||
// all registered transforms | ||
this[_transforms] = []; | ||
// paths -> registered generators | ||
// information about the directory to watch | ||
dir = path.resolve(dir); | ||
this[_dir$2] = { watcher: new Watcher(dir, watch, debounce), dir, read, enc, watch }; | ||
// the transform to run on all files | ||
this[_transform] = transform; | ||
// unique symbols -> registered generators | ||
this[_generators] = new Map(); | ||
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 }; | ||
// original paths of all files currently undergoing some transform/generator | ||
// original paths of all files currently undergoing transformation and symbols of all generators running | ||
this[_pending] = new Set(); | ||
@@ -309,52 +334,16 @@ // original paths -> number of other files they're currently waiting on to exist | ||
get status() { | ||
return this[_status] | ||
} | ||
get origFiles() { | ||
return this[_origFiles] | ||
} | ||
get files() { | ||
if (this[_status] === null) throw new Error('defiler.files: cannot access before calling exec') | ||
return this[_files$1] | ||
} | ||
get origPaths() { | ||
return [...this[_origFiles].keys()].sort() | ||
get paths() { | ||
if (this[_status] === null) throw new Error('defiler.paths: cannot access before calling exec') | ||
return this[_paths] | ||
} | ||
// pre-exec (configuration) methods | ||
// register one or more directories/Watchers | ||
dir(...dirs) { | ||
this[_checkBeforeExec]('dir'); | ||
for (let config of dirs.filter(Boolean)) { | ||
let { dir, read = true, enc = 'utf8', watch = true, debounce = 10 } = config; | ||
dir = path.resolve(dir); | ||
let watcher = new Watcher(dir, watch, debounce); | ||
this[_watchers].push({ watcher, dir, read, enc, watch }); | ||
} | ||
return this | ||
} | ||
// register one or more transforms | ||
transform(...transforms) { | ||
this[_checkBeforeExec]('transform'); | ||
this[_transforms].push(...transforms.filter(Boolean)); | ||
return this | ||
} | ||
// register one or more generators | ||
generator(generators) { | ||
this[_checkBeforeExec]('generator'); | ||
for (let [path$$1, generator] of Object.entries(generators)) { | ||
if (path$$1 && generator) this[_generators].set(path$$1, generator); | ||
} | ||
return this | ||
} | ||
// exec | ||
async exec() { | ||
this[_checkBeforeExec]('exec'); | ||
if (this[_status] !== null) throw new Error('defiler.exec: cannot call more than once') | ||
this[_status] = false; | ||
@@ -366,25 +355,16 @@ this[_processing$1] = true; | ||
}); | ||
// init all Watcher instances; note that all files have pending transforms | ||
let files = []; | ||
await Promise.all( | ||
this[_watchers].map(async ({ watcher, dir, read, enc, watch }) => { | ||
if (watch) { | ||
watcher.on('', ({ event, path: path$$1, stat: stat$$1 }) => { | ||
this[_enqueue$1]({ event, dir, path: path$$1, stat: stat$$1, read, enc }); | ||
}); | ||
} | ||
for (let { path: path$$1, stat: stat$$1 } of await watcher.init()) { | ||
files.push({ dir, path: path$$1, stat: stat$$1, read, enc }); | ||
this[_origFiles].set(path$$1, null); | ||
this[_pending].add(path$$1); | ||
} | ||
}), | ||
); | ||
for (let path$$1 of this[_generators].keys()) this[_pending].add(path$$1); | ||
// init the Watcher instance | ||
let { watcher, watch } = this[_dir$2]; | ||
if (watch) watcher.on('', event => this[_enqueue$1](event)); | ||
let files = await watcher.init(); | ||
// note that all files are pending transformation | ||
for (let { path: path$$1 } of files) { | ||
this[_paths].add(path$$1); | ||
this[_pending].add(path$$1); | ||
} | ||
for (let symbol of this[_generators].keys()) this[_pending].add(symbol); | ||
// process each physical file | ||
for (let { dir, path: path$$1, stat: stat$$1, read, enc } of files) { | ||
this[_wait](this[_processPhysicalFile](dir, path$$1, stat$$1, read, enc)); | ||
} | ||
// process each generated file | ||
for (let path$$1 of this[_generators].keys()) this[_wait](this[_handleGeneratedFile](path$$1)); | ||
for (let { path: path$$1, stat: stat$$1 } of files) this[_wait](this[_processPhysicalFile](path$$1, stat$$1)); | ||
// process each generator | ||
for (let symbol of this[_generators].keys()) this[_wait](this[_processGenerator](symbol)); | ||
// wait and finish up | ||
@@ -399,4 +379,5 @@ await promise; | ||
// add a new non-physical file | ||
async file(file) { | ||
this[_checkAfterExec]('file'); | ||
async add(file) { | ||
if (this[_status] === null) throw new Error('defiler.add: cannot call before calling exec') | ||
if (typeof file !== 'object') throw new TypeError('defiler.add: file must be an object') | ||
let { path: path$$1 } = file; | ||
@@ -406,3 +387,3 @@ if (!(file instanceof File)) file = Object.assign(new File(), file); | ||
this[_files$1].set(path$$1, file); | ||
this.emit('file', { defiler: this, path: path$$1, file }); | ||
this.emit('file', { defiler: this, file }); | ||
this[_found](path$$1); | ||
@@ -414,3 +395,7 @@ this[_processDependents](path$$1); | ||
depend(dependent, path$$1) { | ||
this[_checkAfterExec]('depend'); | ||
if (this[_status] === null) throw new Error('defiler.depend: cannot call before calling exec') | ||
if (typeof dependent !== 'string' && !this[_generators].has(dependent)) { | ||
throw new TypeError('defiler.depend: dependent must be a string') | ||
} | ||
if (typeof path$$1 !== 'string') throw new TypeError('defiler.depend: path must be a string') | ||
if (this[_dependents].has(dependent)) { | ||
@@ -425,10 +410,2 @@ this[_dependents].get(dependent).add(path$$1); | ||
[_checkBeforeExec](methodName) { | ||
if (this[_status] !== null) throw new Error(`Cannot call ${methodName} after calling exec`) | ||
} | ||
[_checkAfterExec](methodName) { | ||
if (this[_status] === null) throw new Error(`Cannot call ${methodName} before calling exec`) | ||
} | ||
// add another promise that must resolve before the initial exec wave can finish | ||
@@ -449,9 +426,11 @@ [_wait](promise) { | ||
while (this[_queue$1].length) { | ||
let { event, dir, path: path$$1, stat: stat$$1, read, enc } = this[_queue$1].shift(); | ||
let { event, path: path$$1, stat: stat$$1 } = this[_queue$1].shift(); | ||
if (event === '+') { | ||
await this[_processPhysicalFile](dir, path$$1, stat$$1, read, enc); | ||
await this[_processPhysicalFile](path$$1, stat$$1); | ||
} else if (event === '-') { | ||
let file = this[_files$1].get(path$$1); | ||
this[_paths].delete(path$$1); | ||
this[_origFiles].delete(path$$1); | ||
this[_files$1].delete(path$$1); | ||
this.emit('deleted', { defiler: this, path: path$$1 }); | ||
this.emit('deleted', { defiler: this, file }); | ||
this[_processDependents](path$$1); | ||
@@ -464,8 +443,10 @@ } | ||
// create a file object for a physical file and process it | ||
async [_processPhysicalFile](dir, path$$1, stat$$1, read, enc) { | ||
let origFile = Object.assign(new File(), { path: path$$1, stat: stat$$1, enc }); | ||
if (read) origFile.bytes = await readFile(dir + '/' + path$$1); | ||
this[_origFiles].set(path$$1, origFile); | ||
this.emit('origFile', { defiler: this, file: origFile }); | ||
await this[_processFile](origFile); | ||
async [_processPhysicalFile](path$$1, stat$$1) { | ||
let { dir, read, enc } = this[_dir$2]; | ||
let file = Object.assign(new File(), { path: path$$1, stat: stat$$1, enc }); | ||
if (read) file.bytes = await readFile(dir + '/' + path$$1); | ||
this[_paths].add(path$$1); | ||
this[_origFiles].set(path$$1, file); | ||
this.emit('read', { defiler: this, file }); | ||
await this[_processFile](file); | ||
} | ||
@@ -478,3 +459,3 @@ | ||
this[_files$1].set(origFile.path, file); | ||
this.emit('file', { defiler: this, path: origFile.path, file }); | ||
this.emit('file', { defiler: this, file }); | ||
this[_found](origFile.path); | ||
@@ -484,3 +465,3 @@ this[_processDependents](origFile.path); | ||
// perform all transforms on a file | ||
// transform a file | ||
async [_transformFile](file) { | ||
@@ -490,12 +471,9 @@ let { path: path$$1 } = file; | ||
try { | ||
for (let transform of this[_transforms]) { | ||
await transform({ | ||
defiler: this, | ||
path: path$$1, | ||
file, | ||
get: dependency => this[_get](path$$1, dependency), | ||
}); | ||
} | ||
await this[_transform]({ | ||
defiler: this, | ||
file, | ||
get: dependency => this[_get](path$$1, dependency), | ||
}); | ||
} catch (error) { | ||
this.emit('error', { defiler: this, path: path$$1, file, error }); | ||
this.emit('error', { defiler: this, file, error }); | ||
} | ||
@@ -510,16 +488,12 @@ this[_pending].delete(path$$1); | ||
// run a generator and transform and add the file | ||
async [_handleGeneratedFile](path$$1) { | ||
let file; | ||
// run the generator given by the symbol | ||
async [_processGenerator](symbol) { | ||
this[_pending].add(symbol); | ||
let generator = this[_generators].get(symbol); | ||
try { | ||
file = new File(path$$1); | ||
await this[_generators].get(path$$1)({ | ||
defiler: this, | ||
file, | ||
get: dependency => this[_get](path$$1, dependency), | ||
}); | ||
await this.file(file); | ||
await generator({ defiler: this, get: dependency => this[_get](symbol, dependency) }); | ||
} catch (error) { | ||
this.emit('error', { defiler: this, path: path$$1, file, error }); | ||
this.emit('error', { defiler: this, generator, error }); | ||
} | ||
this[_pending].delete(symbol); | ||
} | ||
@@ -557,6 +531,6 @@ | ||
for (let dependent of dependents) { | ||
if (this[_generators].has(dependent)) { | ||
this[_handleGeneratedFile](dependent); | ||
} else if (this[_origFiles].has(dependent)) { | ||
if (this[_origFiles].has(dependent)) { | ||
this[_processFile](this[_origFiles].get(dependent)); | ||
} else if (this[_generators].has(dependent)) { | ||
this[_processGenerator](dependent); | ||
} | ||
@@ -563,0 +537,0 @@ } |
@@ -240,7 +240,8 @@ import { readdir, readFile, stat, watch } from 'fs'; | ||
let { | ||
_paths, | ||
_origFiles, | ||
_files: _files$1, | ||
_status, | ||
_watchers, | ||
_transforms, | ||
_dir: _dir$2, | ||
_transform, | ||
_generators, | ||
@@ -254,4 +255,2 @@ _done, | ||
_processing: _processing$1, | ||
_checkBeforeExec, | ||
_checkAfterExec, | ||
_wait, | ||
@@ -262,3 +261,3 @@ _enqueue: _enqueue$1, | ||
_transformFile, | ||
_handleGeneratedFile, | ||
_processGenerator, | ||
_get, | ||
@@ -270,19 +269,45 @@ _processDependents, | ||
class Defiler extends EventEmitter { | ||
constructor() { | ||
constructor({ | ||
dir, | ||
read = true, | ||
enc = 'utf8', | ||
watch: watch$$1 = true, | ||
debounce = 10, | ||
transform, | ||
generators = [], | ||
}) { | ||
if (typeof dir !== 'string') throw new TypeError('defiler: dir must be a string') | ||
if (typeof read !== 'boolean') throw new TypeError('defiler: read must be a boolean') | ||
if (!Buffer.isEncoding(enc)) throw new TypeError('defiler: enc must be a supported encoding') | ||
if (typeof watch$$1 !== 'boolean') throw new TypeError('defiler: watch must be a boolean') | ||
if (typeof debounce !== 'number') throw new TypeError('defiler: debounce must be a number') | ||
if (typeof transform !== 'function') { | ||
throw new TypeError('defiler: transform must be a function') | ||
} | ||
if ( | ||
!generators[Symbol.iterator] || | ||
[...generators].some(generator => typeof generator !== 'function') | ||
) { | ||
throw new TypeError('defiler: generators must be a collection of functions') | ||
} | ||
super(); | ||
// set of original paths for all physical files | ||
this[_paths] = new Set(); | ||
// original paths -> original files for all physical files | ||
this[_origFiles] = new Map(); | ||
// original paths -> transformed files for all physical/generated/etc. files | ||
// original paths -> transformed files for all physical and virtual files | ||
this[_files$1] = new Map(); | ||
// null = exec not called; false = exec pending; true = exec finished | ||
this[_status] = null; | ||
// all registered Watcher instances (one per directory) | ||
this[_watchers] = []; | ||
// all registered transforms | ||
this[_transforms] = []; | ||
// paths -> registered generators | ||
// information about the directory to watch | ||
dir = resolve(dir); | ||
this[_dir$2] = { watcher: new Watcher(dir, watch$$1, debounce), dir, read, enc, watch: watch$$1 }; | ||
// the transform to run on all files | ||
this[_transform] = transform; | ||
// unique symbols -> registered generators | ||
this[_generators] = new Map(); | ||
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 }; | ||
// original paths of all files currently undergoing some transform/generator | ||
// original paths of all files currently undergoing transformation and symbols of all generators running | ||
this[_pending] = new Set(); | ||
@@ -303,52 +328,16 @@ // original paths -> number of other files they're currently waiting on to exist | ||
get status() { | ||
return this[_status] | ||
} | ||
get origFiles() { | ||
return this[_origFiles] | ||
} | ||
get files() { | ||
if (this[_status] === null) throw new Error('defiler.files: cannot access before calling exec') | ||
return this[_files$1] | ||
} | ||
get origPaths() { | ||
return [...this[_origFiles].keys()].sort() | ||
get paths() { | ||
if (this[_status] === null) throw new Error('defiler.paths: cannot access before calling exec') | ||
return this[_paths] | ||
} | ||
// pre-exec (configuration) methods | ||
// register one or more directories/Watchers | ||
dir(...dirs) { | ||
this[_checkBeforeExec]('dir'); | ||
for (let config of dirs.filter(Boolean)) { | ||
let { dir, read = true, enc = 'utf8', watch: watch$$1 = true, debounce = 10 } = config; | ||
dir = resolve(dir); | ||
let watcher = new Watcher(dir, watch$$1, debounce); | ||
this[_watchers].push({ watcher, dir, read, enc, watch: watch$$1 }); | ||
} | ||
return this | ||
} | ||
// register one or more transforms | ||
transform(...transforms) { | ||
this[_checkBeforeExec]('transform'); | ||
this[_transforms].push(...transforms.filter(Boolean)); | ||
return this | ||
} | ||
// register one or more generators | ||
generator(generators) { | ||
this[_checkBeforeExec]('generator'); | ||
for (let [path, generator] of Object.entries(generators)) { | ||
if (path && generator) this[_generators].set(path, generator); | ||
} | ||
return this | ||
} | ||
// exec | ||
async exec() { | ||
this[_checkBeforeExec]('exec'); | ||
if (this[_status] !== null) throw new Error('defiler.exec: cannot call more than once') | ||
this[_status] = false; | ||
@@ -360,25 +349,16 @@ this[_processing$1] = true; | ||
}); | ||
// init all Watcher instances; note that all files have pending transforms | ||
let files = []; | ||
await Promise.all( | ||
this[_watchers].map(async ({ watcher, dir, read, enc, watch: watch$$1 }) => { | ||
if (watch$$1) { | ||
watcher.on('', ({ event, path, stat: stat$$1 }) => { | ||
this[_enqueue$1]({ event, dir, path, stat: stat$$1, read, enc }); | ||
}); | ||
} | ||
for (let { path, stat: stat$$1 } of await watcher.init()) { | ||
files.push({ dir, path, stat: stat$$1, read, enc }); | ||
this[_origFiles].set(path, null); | ||
this[_pending].add(path); | ||
} | ||
}), | ||
); | ||
for (let path of this[_generators].keys()) this[_pending].add(path); | ||
// init the Watcher instance | ||
let { watcher, watch: watch$$1 } = this[_dir$2]; | ||
if (watch$$1) watcher.on('', event => this[_enqueue$1](event)); | ||
let files = await watcher.init(); | ||
// note that all files are pending transformation | ||
for (let { path } of files) { | ||
this[_paths].add(path); | ||
this[_pending].add(path); | ||
} | ||
for (let symbol of this[_generators].keys()) this[_pending].add(symbol); | ||
// process each physical file | ||
for (let { dir, path, stat: stat$$1, read, enc } of files) { | ||
this[_wait](this[_processPhysicalFile](dir, path, stat$$1, read, enc)); | ||
} | ||
// process each generated file | ||
for (let path of this[_generators].keys()) this[_wait](this[_handleGeneratedFile](path)); | ||
for (let { path, stat: stat$$1 } of files) this[_wait](this[_processPhysicalFile](path, stat$$1)); | ||
// process each generator | ||
for (let symbol of this[_generators].keys()) this[_wait](this[_processGenerator](symbol)); | ||
// wait and finish up | ||
@@ -393,4 +373,5 @@ await promise; | ||
// add a new non-physical file | ||
async file(file) { | ||
this[_checkAfterExec]('file'); | ||
async add(file) { | ||
if (this[_status] === null) throw new Error('defiler.add: cannot call before calling exec') | ||
if (typeof file !== 'object') throw new TypeError('defiler.add: file must be an object') | ||
let { path } = file; | ||
@@ -400,3 +381,3 @@ if (!(file instanceof File)) file = Object.assign(new File(), file); | ||
this[_files$1].set(path, file); | ||
this.emit('file', { defiler: this, path, file }); | ||
this.emit('file', { defiler: this, file }); | ||
this[_found](path); | ||
@@ -408,3 +389,7 @@ this[_processDependents](path); | ||
depend(dependent, path) { | ||
this[_checkAfterExec]('depend'); | ||
if (this[_status] === null) throw new Error('defiler.depend: cannot call before calling exec') | ||
if (typeof dependent !== 'string' && !this[_generators].has(dependent)) { | ||
throw new TypeError('defiler.depend: dependent must be a string') | ||
} | ||
if (typeof path !== 'string') throw new TypeError('defiler.depend: path must be a string') | ||
if (this[_dependents].has(dependent)) { | ||
@@ -419,10 +404,2 @@ this[_dependents].get(dependent).add(path); | ||
[_checkBeforeExec](methodName) { | ||
if (this[_status] !== null) throw new Error(`Cannot call ${methodName} after calling exec`) | ||
} | ||
[_checkAfterExec](methodName) { | ||
if (this[_status] === null) throw new Error(`Cannot call ${methodName} before calling exec`) | ||
} | ||
// add another promise that must resolve before the initial exec wave can finish | ||
@@ -443,9 +420,11 @@ [_wait](promise) { | ||
while (this[_queue$1].length) { | ||
let { event, dir, path, stat: stat$$1, read, enc } = this[_queue$1].shift(); | ||
let { event, path, stat: stat$$1 } = this[_queue$1].shift(); | ||
if (event === '+') { | ||
await this[_processPhysicalFile](dir, path, stat$$1, read, enc); | ||
await this[_processPhysicalFile](path, stat$$1); | ||
} else if (event === '-') { | ||
let file = this[_files$1].get(path); | ||
this[_paths].delete(path); | ||
this[_origFiles].delete(path); | ||
this[_files$1].delete(path); | ||
this.emit('deleted', { defiler: this, path }); | ||
this.emit('deleted', { defiler: this, file }); | ||
this[_processDependents](path); | ||
@@ -458,8 +437,10 @@ } | ||
// create a file object for a physical file and process it | ||
async [_processPhysicalFile](dir, path, stat$$1, read, enc) { | ||
let origFile = Object.assign(new File(), { path, stat: stat$$1, enc }); | ||
if (read) origFile.bytes = await readFile$1(dir + '/' + path); | ||
this[_origFiles].set(path, origFile); | ||
this.emit('origFile', { defiler: this, file: origFile }); | ||
await this[_processFile](origFile); | ||
async [_processPhysicalFile](path, stat$$1) { | ||
let { dir, read, enc } = this[_dir$2]; | ||
let file = Object.assign(new File(), { path, stat: stat$$1, enc }); | ||
if (read) file.bytes = await readFile$1(dir + '/' + path); | ||
this[_paths].add(path); | ||
this[_origFiles].set(path, file); | ||
this.emit('read', { defiler: this, file }); | ||
await this[_processFile](file); | ||
} | ||
@@ -472,3 +453,3 @@ | ||
this[_files$1].set(origFile.path, file); | ||
this.emit('file', { defiler: this, path: origFile.path, file }); | ||
this.emit('file', { defiler: this, file }); | ||
this[_found](origFile.path); | ||
@@ -478,3 +459,3 @@ this[_processDependents](origFile.path); | ||
// perform all transforms on a file | ||
// transform a file | ||
async [_transformFile](file) { | ||
@@ -484,12 +465,9 @@ let { path } = file; | ||
try { | ||
for (let transform of this[_transforms]) { | ||
await transform({ | ||
defiler: this, | ||
path, | ||
file, | ||
get: dependency => this[_get](path, dependency), | ||
}); | ||
} | ||
await this[_transform]({ | ||
defiler: this, | ||
file, | ||
get: dependency => this[_get](path, dependency), | ||
}); | ||
} catch (error) { | ||
this.emit('error', { defiler: this, path, file, error }); | ||
this.emit('error', { defiler: this, file, error }); | ||
} | ||
@@ -504,16 +482,12 @@ this[_pending].delete(path); | ||
// run a generator and transform and add the file | ||
async [_handleGeneratedFile](path) { | ||
let file; | ||
// run the generator given by the symbol | ||
async [_processGenerator](symbol) { | ||
this[_pending].add(symbol); | ||
let generator = this[_generators].get(symbol); | ||
try { | ||
file = new File(path); | ||
await this[_generators].get(path)({ | ||
defiler: this, | ||
file, | ||
get: dependency => this[_get](path, dependency), | ||
}); | ||
await this.file(file); | ||
await generator({ defiler: this, get: dependency => this[_get](symbol, dependency) }); | ||
} catch (error) { | ||
this.emit('error', { defiler: this, path, file, error }); | ||
this.emit('error', { defiler: this, generator, error }); | ||
} | ||
this[_pending].delete(symbol); | ||
} | ||
@@ -551,6 +525,6 @@ | ||
for (let dependent of dependents) { | ||
if (this[_generators].has(dependent)) { | ||
this[_handleGeneratedFile](dependent); | ||
} else if (this[_origFiles].has(dependent)) { | ||
if (this[_origFiles].has(dependent)) { | ||
this[_processFile](this[_origFiles].get(dependent)); | ||
} else if (this[_generators].has(dependent)) { | ||
this[_processGenerator](dependent); | ||
} | ||
@@ -557,0 +531,0 @@ } |
{ | ||
"name": "defiler", | ||
"version": "0.11.2", | ||
"version": "0.12.0", | ||
"description": "A small, strange building block", | ||
@@ -5,0 +5,0 @@ "keywords": ["build", "framework", "async", "watch"], |
@@ -1,27 +0,9 @@ | ||
# Defiler | ||
# Defiler: A small, strange building block. | ||
[![npm version](https://img.shields.io/npm/v/defiler.svg?style=flat-square)](https://www.npmjs.com/package/defiler) | ||
A small, strange building block. | ||
## Motivation | ||
Defiler is a small build tool framework with strange opinions. It was born out of a desire to redo the build process for my various personal websites. I wanted something that was very flexible, kept everything in memory as it was building, and could handle arbitrary dependencies between files so that when something changed, only the necessary files would be re-built. | ||
## Concepts | ||
Defiler is a build tool for people who find build tools interesting. | ||
Defiler's concept of a file is something that can come from one of two places: a physical file on the disk, or a virtual file that is generated by a callback you pass to Defiler. These two types of files differ slightly in how they are treated, but for the most part Defiler handles them both the same. | ||
Files of both types are run through the gamut of transforms you register with Defiler. Each transform mutates the object representing the file in-place, and returns a promise indicating when it's finished. | ||
Files' names can be changed as they're transformed, but the main way to refer to them will continue to be by their original path. This makes Defiler's job a bit easier, but is also probably more useful anyway. If you want to translate LESS into CSS and then inject it into a particular script, you're going to want to write `import './path/to/file.less'` not `import './path/to/file.css'`. | ||
Files can be made to depend on other files, so that changes to a dependency cause the depender to be re-transformed. For physical files, the file does not need to be re-read from the disk before it can be re-transformed, as the original version is kept in memory. | ||
Any transform or generator can also create additional files (which will then be run through all of the transforms). There's currently no way to make this additional file depend on any others for the purposes of automatic re-transformation, as the file would generally just be re-added when that transform or generator is run again. | ||
If you need to write the transformed files to disk, that's its own transform. Just leave the file object untouched but write the file to disk in the appropriate location and return a promise indicating when you're done. | ||
If you need some task management, that's outside the scope of this library. Just use `await` and `Promise.all`. | ||
## Requirements | ||
@@ -36,2 +18,3 @@ | ||
- [api](API.md#readme) | ||
- [cookbook](COOKBOOK.md#readme) | ||
- [changelog](CHANGELOG.md#readme) | ||
@@ -38,0 +21,0 @@ - [homepage](https://cndtr.io/defiler/) |
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
110371
968
27