My trusty s3-publish module fell over when I last attempted to update my blog.

The error informed me that the maximum call stack size had been exceeded. In retrospect, it’s not hard to see why.

Escaping Callback Hell

At the time I wrote s3-publish, I was extremely enamored with the async and neo-async modules. So much so that I began to see every problem as a nail to be hammered with a callback-based queue. Eventually, my static blog was comprised of enough files to exhaust the maximum callback stack. Yikes.

Clearly, my approach had to be completely rethought. As luck would have it, I have since become very fond of the async/await syntax which is a much better fit. Adding a dash of p-limit allowed a specific number of promises to be executed in parallel and I was off to the races.

Redesigning the API

As part of the rethought approach, I decided to expose a proper API this time. Version 1x of s3-publish was first and foremost a CLI and it’s implementation did not give much thought to exporting the functionality in useful bundles.

To that end, I also decided to give yarn workspaces a big hug and make the project a monorepo aided by lerna.

s3-publish is now a meta package that bundles the CLI and all dependencies with webpack.

Rethinking Configuration

Unfortunately, support for the old configuration schema had to be dropped in favor of something more versatile. See the ConfigFile interface documentation for details.

The default configuration file has been renamed to .s3p.config.js and the new schemaVersion is 2.

The --config option can be used to specify an alternate config file name if you’d prefer to keep using s3p.config.js.

If any users have trouble migrating their s3p.config.js files to .s3p.config.js files, please create an issue on GitHub and I’ll do my best to help.


Project Sprawl

Along the way, s3-publish has spawned a few sister projects. These are separate in that they are not part of the monorepo, but they were created to address a specific need in s3-publish:

Wrap Up

I’m quite proud of how this rewrite turned out and I hope it’s useful to folks. If I broke something you rely on, feel free to create an issue on GitHub.