winterspec
Version:
Write Winter-CG compatible routes with filesystem routing and tons of features
71 lines (70 loc) • 3.15 kB
JavaScript
import path from "path";
import { getTempPathInApp } from "../../bundle/get-temp-path-in-app.js";
import { bundleAndWatch } from "../../bundle/watch.js";
import { createBirpcGroup } from "birpc";
import { formatMessages } from "esbuild";
import { AsyncWorkTracker } from "../../lib/async-work-tracker.js";
/**
* Start a headless WinterSpec dev bundler. It will continuously watch your code and rebuild on changes.
* For this to be useful, you'll probably want to also start a headless dev server.
* This must be run within a native context (Node.js, Bun, or Deno).
*/
export const startHeadlessDevBundler = async ({ config, initialRpcChannels, }) => {
const tempDir = await getTempPathInApp(config.rootDirectory);
const devBundlePath = path.join(tempDir, "dev-bundle.js");
const buildTracker = new AsyncWorkTracker();
const rpcFunctions = {
async waitForAvailableBuild() {
return buildTracker.waitForResult();
},
};
const birpc = createBirpcGroup(rpcFunctions, initialRpcChannels ?? [], { eventNames: ["onBuildStart", "onBuildEnd"] });
const { stop } = await bundleAndWatch({
rootDirectory: config.rootDirectory,
routesDirectory: config.routesDirectory,
bundledAdapter: config.platform === "wintercg-minimal" ? "wintercg-minimal" : undefined,
esbuild: {
platform: config.platform === "wintercg-minimal" ? "browser" : "node",
packages: config.platform === "node" ? "external" : undefined,
format: config.platform === "wintercg-minimal" ? "cjs" : "esm",
outfile: devBundlePath,
write: true,
plugins: [
{
name: "watch",
setup(build) {
build.onStart(async () => {
buildTracker.beginAsyncWork();
await birpc.broadcast.onBuildStart();
});
build.onEnd(async (result) => {
let build;
if (result.errors.length === 0) {
build = {
type: "success",
bundlePath: devBundlePath,
buildUpdatedAtMs: Date.now(),
};
}
else {
build = {
type: "failure",
errorMessage: (await formatMessages(result.errors, {
kind: "error",
})).join("\n"),
buildUpdatedAtMs: Date.now(),
};
}
buildTracker.finishAsyncWork(build);
await birpc.broadcast.onBuildEnd(build);
});
},
},
],
},
});
return {
stop,
birpc,
};
};