UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

161 lines (136 loc) 4.83 kB
import * as glob from "glob"; import * as fs from "fs-extra"; import * as chokidar from "chokidar"; import { each } from "realm-utils"; import { ensureDir, string2RegExp } from "../Utils"; import { SparkyFile } from "./SparkyFile"; import { log } from "./Sparky"; import { Plugin } from '../core/WorkFlowContext'; import { parse, SparkyFilePatternOptions } from "./SparkyFilePattern"; export class SparkFlow { private activities = []; private watcher: any; private files: SparkyFile[]; private completedCallback: any; private initialWatch = false; constructor() { } public glob(globs: string[], opts?: SparkyFilePatternOptions): SparkFlow { this.activities.push(() => this.getFiles(globs, opts)); return this; } public stopWatching() { if (this.watcher) { this.watcher.close(); } } public watch(globs: string[], opts?: SparkyFilePatternOptions): SparkFlow { this.files = []; log.echoStatus(`Watch ${globs}`) this.activities.push(() => new Promise((resolve, reject) => { var chokidarOptions = { cwd: opts ? opts.base : null }; this.watcher = chokidar.watch(globs, chokidarOptions) .on('all', (event, fp) => { if (event === 'addDir' || event === 'unlinkDir') return if (this.initialWatch) { this.files = []; log.echoStatus(`Changed ${fp}`) } let info = parse(fp, opts); this.files.push(new SparkyFile(info.filepath, info.root)) if (this.initialWatch) { // call it again this.exec(); } }).on('ready', () => { this.initialWatch = true; log.echoStatus(`Resolved ${this.files.length} files`) this.activities[0] = undefined; resolve(); }); })); return this; } public completed(fn: any): SparkFlow { this.completedCallback = fn; return this; } /** Gets all user files */ protected getFiles(globs: string[], opts?: SparkyFilePatternOptions): Promise<SparkyFile[]> { this.files = []; const getFilePromises = []; globs.forEach(g => { getFilePromises.push(this.getFile(g, opts)); }) return Promise.all(getFilePromises) .then(results => { this.files = [].concat.apply([], results); return this.files; }) } protected getFile(globString, opts?: SparkyFilePatternOptions) { let info = parse(globString, opts) return new Promise((resolve, reject) => { if (!info.isGlob) { return resolve([new SparkyFile(info.filepath, info.root)]) } glob(info.glob, (err, files: string[]) => { if (err) { return reject(err); } return resolve(files.map(file => new SparkyFile(file, info.root))) }); }); } /** * Removes folder if exists * @param dest */ public clean(dest: string): SparkFlow { this.activities.push(() => new Promise((resolve, reject) => { fs.remove(ensureDir(dest), err => { if (err) return reject(err); return resolve(); }) }) ); return this; } public plugin(plugin: Plugin): SparkFlow { this.activities.push(() => { //Promise.all(this.files.map(file => file.copy(dest))) //File.createByName(collection, "sd") }); return this; } public file(mask: string, fn: any) { this.activities.push(() => { let regexp = string2RegExp(mask); return each(this.files, (file: SparkyFile) => { if (regexp.test(file.filepath)) { log.echoStatus(`Captured file ${file.homePath}`); return fn(file); } }) }); return this; } public dest(dest: string): SparkFlow { log.echoStatus(`Copy to ${dest}`) this.activities.push(() => Promise.all(this.files.map(file => file.copy(dest))) ); return this; } public exec() { return each(this.activities, (activity: any) => activity && activity()) .then(() => { if (this.completedCallback) { this.completedCallback(this.files); } this.files = []; }); } }