API reference › @evolu/nodejs › runMain
Call Signature
function runMain<T, E>(
main: Task<T, E>,
options?: RunMainOptions,
): Promise<void>;
Defined in: packages/nodejs/src/Task.ts:121
Runs the main Task of a Node.js command or service.
A command does a finite job, such as importing data. A service handles ongoing work, such as accepting connections. Choose a mode for how the program reports an interruption:
"command": A termination signal means the job was interrupted. After cleanup, use the conventional signal exit status, such as 130 for Ctrl-C, unlessprocess.exitCodeis already set."service"(default): A termination signal is an expected way to stop the service. Graceful shutdown does not set a failure exit status.
Both modes create one root Run and wait for cleanup. The mode controls
signal exit status; the main Task controls how long runMain waits.
Lifetime
When the main Task returns void, runMain finishes after the Task and root
Run cleanup. It does not force the Node.js process to exit.
A service can return a live Resource, such as the relay created by
createRelay. This transfers ownership to runMain, which waits for
shutdown and then disposes the Resource. It must remain usable after the
creating Task finishes; do not dispose it before returning it.
Alternatively, the main Task can own its resources with using or await using while awaiting waitForAbort with run(waitForAbort). Waiting
for abort does not itself keep Node.js running: the service needs active
work, such as a listening server.
Shutdown and errors
Handles SIGINT (Ctrl-C), SIGTERM (termination by the OS or a service
host), and SIGBREAK (Ctrl-Break on Windows). The first signal logs shutdown
progress, aborts the root Run, and waits for cleanup. A second signal exits
immediately with its conventional signal status, abandoning cleanup. Signals
are still handled during final cleanup.
An error returned by the main Task is fatal. getOrThrow preserves it
in Error.cause; the Run reports the failure and finishes cleanup. Every
reported defect sets process.exitCode to 1, including an observer defect
that does not abort the Run. The default reporter logs to the configured
Evolu console.
Escaped uncaught exceptions and unhandled rejections remain under Node.js native reporting and termination.
Example
A command finishes when its main Task completes:
import { assertTrue, ok, type Task } from "@evolu/common";
import { runMain } from "@evolu/nodejs";
let completed = false;
const command: Task<void> = () => {
completed = true;
return ok();
};
await runMain(command, { mode: "command" });
assertTrue(completed);
Call Signature
function runMain<D>(
deps: RunCustomDeps<D>,
options?: RunMainOptions,
): <T, E>(main: Task<T, E, D>) => Promise<void>;
Defined in: packages/nodejs/src/Task.ts:126
With custom dependencies.