| 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 | */ |
| 10 | import type * as Effect from "effect/Effect" |
| 11 | import { 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 | */ |
| 36 | export 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 | }) |