1/**
2 * Browser helper for running a root Effect program.
3 *
4 * This module exports `runMain`, a browser version of the main Effect runner.
5 * It forwards runner options to the core runtime and adds a `pagehide`
6 * listener that interrupts the main fiber when the document is discarded.
7 *
8 * @since 4.0.0
9 */
10import type * as Effect from "effect/Effect"
11import { makeRunMain, type Teardown } from "effect/Runtime"
12
13/**
14 * Runs an effect as the browser main program and interrupts its fiber when the document is discarded.
15 *
16 * **When to use**
17 *
18 * Use to launch a browser page, single-page application, demo, or browser test
19 * harness as a root Effect program.
20 *
21 * **Details**
22 *
23 * Supports both direct and curried call forms. Options are forwarded to
24 * `makeRunMain`, including `disableErrorReporting` and custom `teardown`
25 * behavior. A persisted `pagehide` event is ignored because the document is
26 * entering the back/forward cache and may be restored.
27 *
28 * **Gotchas**
29 *
30 * The `pagehide` interruption is best-effort. Browser teardown may prevent
31 * asynchronous finalizers, network work, timers, or prompts from completing.
32 *
33 * @category running
34 * @since 4.0.0
35 */
36export const runMain: {
37 (
38 options?: {
39 readonly disableErrorReporting?: boolean | undefined
40 readonly teardown?: Teardown | undefined
41 }
42 ): <E, A>(effect: Effect.Effect<A, E>) => void
43 <E, A>(
44 effect: Effect.Effect<A, E>,
45 options?: {
46 readonly disableErrorReporting?: boolean | undefined
47 readonly teardown?: Teardown | undefined
48 }
49 ): void
50} = makeRunMain(({ fiber, teardown }) => {
51 function onPageHide(event: PageTransitionEvent) {
52 if (!event.persisted) {
53 fiber.interruptUnsafe(fiber.id)
54 }
55 }
56
57 globalThis.addEventListener("pagehide", onPageHide)
58 fiber.addObserver((exit) => {
59 globalThis.removeEventListener("pagehide", onPageHide)
60 teardown(exit, () => {})
61 })
62})