1/**
2 * Node-compatible process runner for Effect programs.
3 *
4 * This module provides the shared `runMain` implementation used by
5 * Node-compatible platform packages. It runs one Effect as the main process
6 * fiber, interrupts that fiber on `SIGINT` or `SIGTERM`, and delegates final
7 * exit-code handling to the configured teardown.
8 *
9 * @since 4.0.0
10 */
11import type { Effect } from "effect/Effect"
12import * as Runtime from "effect/Runtime"
13
14/**
15 * Runs an Effect as the Node process main program, interrupting the fiber on
16 * `SIGINT` or `SIGTERM` and invoking the configured teardown to determine the
17 * process exit code.
18 *
19 * @category running
20 * @since 4.0.0
21 */
22export const runMain: {
23 (
24 options?: {
25 readonly disableErrorReporting?: boolean | undefined
26 readonly teardown?: Runtime.Teardown | undefined
27 }
28 ): <E, A>(effect: Effect<A, E>) => void
29 <E, A>(
30 effect: Effect<A, E>,
31 options?: {
32 readonly disableErrorReporting?: boolean | undefined
33 readonly teardown?: Runtime.Teardown | undefined
34 }
35 ): void
36} = Runtime.makeRunMain(({
37 fiber,
38 teardown
39}) => {
40 let receivedSignal = false
41
42 fiber.addObserver((exit) => {
43 process.removeListener("SIGINT", onSigint)
44 process.removeListener("SIGTERM", onSigint)
45 teardown(exit, (code) => {
46 if (receivedSignal || code !== 0) {
47 process.exit(code)
48 }
49 })
50 })
51
52 function onSigint() {
53 receivedSignal = true
54 fiber.interruptUnsafe(fiber.id)
55 }
56
57 process.on("SIGINT", onSigint)
58 process.on("SIGTERM", onSigint)
59})