This issue was originally identified in voxpelli/voxpelli.github.com#32
Problem
The DomStack class exports a programmatic build() method, but it is difficult to use for isolated, repeatable tests because of three compounding issues:
-
--copy paths must be absolute — The CLI resolves paths with resolve(cwd, p), but the DomStack constructor does not. Passing relative paths like 'images' silently fails or produces unexpected copy behavior.
-
Build errors are opaque across the worker boundary — build() throws a DomStackAggregateError but each inner error's cause is serialized to a plain object, losing the original stack trace. The errorData property containing the page path is attached but not printed by the default formatter.
-
No built-in temp directory or dry-run support — Testing requires manually creating temp directories, building into them, asserting on the output, and cleaning up.
Current behavior
The constructor does not resolve copy paths
constructor (src, dest, opts = {}) {
// ...
const copyDirs = opts?.copy ?? []
this.opts = {
...opts,
ignore: [
...DEFAULT_IGNORES,
basename(dest),
...copyDirs.map(dir => basename(dir)), // Only uses basename, not resolve
],
}
}
The CLI resolves paths before passing them to the constructor, but programmatic users must know to do this themselves.
Test suites depend on a pre-existing build
Projects end up with:
"test": "run-s check build test:build"
Tests cannot run in isolation — they require a full build first. This means tests are slow, stateful, and cannot run in parallel.
Proposed solution
1. Resolve copy paths in the constructor (bug fix)
constructor (src, dest, opts = {}) {
const basedir = dirname(resolve(src))
const copyDirs = (opts?.copy ?? []).map(dir => resolve(basedir, dir))
// ...
}
2. Improve error reporting across the worker boundary
Include page path in error messages when available:
buildReport.errors = workerReport.errors.map(({ error, errorData = {} }) => {
const pagePath = errorData.page?.path || errorData.template?.path || 'unknown';
const richError = new Error(
`${error.message} (page: "${pagePath}")`,
{ cause: error.cause }
);
richError.pageInfo = errorData.page;
return richError;
});
3. Add a test helper module
Export a lightweight test helper from @domstack/static/test:
export async function testBuild(src, opts = {}) {
const dest = await mkdtemp(join(tmpdir(), 'domstack-test-'));
const ds = new DomStack(resolve(src), dest, {
...opts,
copy: (opts.copy ?? []).map(p => resolve(p)),
});
const results = await ds.build();
return {
dest,
results,
readOutput: (path) => readFile(join(dest, path), 'utf8'),
cleanup: () => rm(dest, { recursive: true, force: true }),
};
}
Recommendation: Fix copy path resolution and improve error reporting as bug fixes, then ship the test helper as an enhancement.
Note
DomStack already has a test-cases/ directory with programmatic DomStack instantiation tests — so the pattern is proven, it just needs path resolution fixes and error quality improvements.
Problem
The
DomStackclass exports a programmaticbuild()method, but it is difficult to use for isolated, repeatable tests because of three compounding issues:--copypaths must be absolute — The CLI resolves paths withresolve(cwd, p), but theDomStackconstructor does not. Passing relative paths like'images'silently fails or produces unexpected copy behavior.Build errors are opaque across the worker boundary —
build()throws aDomStackAggregateErrorbut each inner error'scauseis serialized to a plain object, losing the original stack trace. TheerrorDataproperty containing the page path is attached but not printed by the default formatter.No built-in temp directory or dry-run support — Testing requires manually creating temp directories, building into them, asserting on the output, and cleaning up.
Current behavior
The constructor does not resolve
copypathsThe CLI resolves paths before passing them to the constructor, but programmatic users must know to do this themselves.
Test suites depend on a pre-existing build
Projects end up with:
Tests cannot run in isolation — they require a full build first. This means tests are slow, stateful, and cannot run in parallel.
Proposed solution
1. Resolve
copypaths in the constructor (bug fix)2. Improve error reporting across the worker boundary
Include page path in error messages when available:
3. Add a test helper module
Export a lightweight test helper from
@domstack/static/test:Recommendation: Fix copy path resolution and improve error reporting as bug fixes, then ship the test helper as an enhancement.
Note
DomStack already has a
test-cases/directory with programmaticDomStackinstantiation tests — so the pattern is proven, it just needs path resolution fixes and error quality improvements.