cogs
Version:
The fast file transform pipeline.
77 lines (61 loc) • 1.66 kB
JavaScript
import npath from 'node:path';
import { watch } from 'watchy';
import buildConfig from '#src/build-config.js';
import bustCache from '#src/bust-cache.js';
import getConfig from '#src/get-config.js';
export default async ({
configPath = 'cogs.js',
onError = async () => {},
onEnd = async () => {},
onResult = async () => {},
onStart = async () => {},
watchPaths = []
}) => {
let building = false;
let changedPaths = new Set();
let config;
const build = async () => {
if (building) return;
building = true;
const paths = changedPaths;
changedPaths = new Set();
if (paths.has(configPath)) {
config = null;
} else if (config) {
await Promise.all(
Array.from(paths).map(path => bustCache({ config, path }))
);
}
if (!config) config = await getConfig(configPath);
await onStart();
await buildConfig({
config,
onResult: async result => {
const { didChange, targetPath } = result;
if (didChange) await bustCache({ config, path: targetPath });
return onResult(result);
}
});
await onEnd();
building = false;
if (changedPaths.size) await build();
};
if (!watchPaths.length) return build();
const tryBuild = async () => {
try {
await build();
} catch (er) {
await onError(er);
}
};
const handleChangedPath = paths => {
for (const path of paths) changedPaths.add(npath.relative('.', path));
tryBuild();
};
const closeWatcher = watch({
onChange: handleChangedPath,
patterns: [].concat(configPath, watchPaths)
});
await tryBuild();
return closeWatcher;
};