trigger.dev
Version:
A Command-Line Interface for Trigger.dev projects
156 lines • 6.38 kB
JavaScript
import { bundleWorker, createBuildManifestFromBundle, getBundleResultFromBuild, logBuildFailure, logBuildWarnings, } from "../build/bundle.js";
import { createBuildContext, notifyExtensionOnBuildComplete, notifyExtensionOnBuildStart, resolvePluginsForContext, } from "../build/extensions.js";
import { createExternalsBuildExtension, resolveAlwaysExternal } from "../build/externals.js";
import { eventBus } from "../utilities/eventBus.js";
import { logger } from "../utilities/logger.js";
import { clearTmpDirs, getStoreDir, getTmpDir, } from "../utilities/tempDirectories.js";
import { startDevOutput } from "./devOutput.js";
import { startWorkerRuntime } from "./devSupervisor.js";
import { startMcpServer, stopMcpServer } from "./mcpServer.js";
import { writeJSONFile } from "../utilities/fileSystem.js";
import { join } from "node:path";
export async function startDevSession({ rawConfig, name, rawArgs, client, dashboardUrl, keepTmpFiles, }) {
clearTmpDirs(rawConfig.workingDir);
const destination = getTmpDir(rawConfig.workingDir, "build", keepTmpFiles);
// Create shared store directory for deduplicating chunk files across rebuilds
const storeDir = getStoreDir(rawConfig.workingDir, keepTmpFiles);
const runtime = await startWorkerRuntime({
name,
config: rawConfig,
args: rawArgs,
client,
dashboardUrl,
});
if (rawArgs.mcp) {
await startMcpServer({
port: rawArgs.mcpPort,
cliApiClient: client,
devSession: {
dashboardUrl,
projectRef: rawConfig.project,
},
});
}
const stopOutput = startDevOutput({
name,
dashboardUrl,
config: rawConfig,
args: rawArgs,
});
const alwaysExternal = await resolveAlwaysExternal(client);
logger.debug("Starting dev session", {
destination: destination.path,
rawConfig,
alwaysExternal,
});
const externalsExtension = createExternalsBuildExtension("dev", rawConfig, alwaysExternal);
const buildContext = createBuildContext("dev", rawConfig);
buildContext.prependExtension(externalsExtension);
await notifyExtensionOnBuildStart(buildContext);
const pluginsFromExtensions = resolvePluginsForContext(buildContext);
async function updateBundle(bundle, workerDir) {
let buildManifest = await createBuildManifestFromBundle({
bundle,
destination: destination.path,
resolvedConfig: rawConfig,
workerDir: workerDir?.path,
environment: "dev",
target: "dev",
storeDir,
});
logger.debug("Created build manifest from bundle", { buildManifest });
await writeJSONFile(join(workerDir?.path ?? destination.path, "metafile.json"), bundle.metafile);
buildManifest = await notifyExtensionOnBuildComplete(buildContext, buildManifest);
try {
logger.debug("Updated bundle", { bundle, buildManifest });
await runtime.initializeWorker(buildManifest, bundle.metafile, workerDir?.remove ?? (() => { }));
}
catch (error) {
if (error instanceof Error) {
eventBus.emit("backgroundWorkerIndexingError", buildManifest, error);
}
else {
logger.error("Error updating bundle", { error });
}
}
}
async function updateBuild(build, workerDir) {
const bundle = await getBundleResultFromBuild("dev", rawConfig.workingDir, rawConfig, build, storeDir);
if (bundle) {
await updateBundle({ ...bundle, stop: undefined }, workerDir);
}
}
let bundled = false;
const onEnd = {
name: "on-end",
setup(b) {
b.onStart(() => {
logger.debug("on-end plugin started");
if (bundled) {
eventBus.emit("rebuildStarted", "dev");
}
});
b.onEnd(async (result) => {
const errors = result.errors;
const warnings = result.warnings;
if (errors.length > 0) {
logBuildFailure(errors, warnings);
return;
}
if (warnings.length > 0) {
logBuildWarnings(warnings);
}
if (!bundled) {
bundled = true;
logger.debug("First bundle, no need to update bundle");
return;
}
const workerDir = getTmpDir(rawConfig.workingDir, "build", keepTmpFiles);
await updateBuild(result, workerDir);
});
},
};
async function runBundle() {
eventBus.emit("buildStarted", "dev");
try {
// Use glob to find initial entryPoints
// Use chokidar to watch for entryPoints changes (e.g. added or removed?)
// When there is a change, update entryPoints and start a new build with watch: true
const bundleResult = await bundleWorker({
target: "dev",
cwd: rawConfig.workingDir,
destination: destination.path,
watch: true,
resolvedConfig: rawConfig,
plugins: [...pluginsFromExtensions, onEnd],
jsxFactory: rawConfig.build.jsx.factory,
jsxFragment: rawConfig.build.jsx.fragment,
jsxAutomatic: rawConfig.build.jsx.automatic,
storeDir,
});
await updateBundle(bundleResult);
return bundleResult.stop;
}
catch (error) {
if (error instanceof Error) {
eventBus.emit("buildFailed", "dev", error);
}
else {
eventBus.emit("buildFailed", "dev", new Error(String(error)));
}
throw error;
}
}
const stopBundling = await runBundle();
return {
stop: () => {
logger.debug("Stopping dev session");
destination.remove();
stopBundling?.().catch((error) => { });
runtime.shutdown().catch((error) => { });
stopOutput();
stopMcpServer();
},
};
}
//# sourceMappingURL=devSession.js.map