// Browser Module - Effects for browser/DOM interaction // // This module provides effects for interacting with the browser DOM, // local storage, and other browser APIs. // Opaque Element type (represents a DOM element) type Element = | DomElement(Int) // DOM manipulation effect effect Dom { fn getElementById(id: String): Option fn querySelector(selector: String): Option fn querySelectorAll(selector: String): List fn createElement(tag: String): Element fn createTextNode(text: String): Element fn appendChild(parent: Element, child: Element): Unit fn removeChild(parent: Element, child: Element): Unit fn setAttribute(element: Element, name: String, value: String): Unit fn removeAttribute(element: Element, name: String): Unit fn setProperty(element: Element, name: String, value: String): Unit fn setTextContent(element: Element, text: String): Unit fn getBody(): Element fn focus(element: Element): Unit fn blur(element: Element): Unit } // Browser storage effect effect Storage { fn getItem(key: String): Option fn setItem(key: String, value: String): Unit fn removeItem(key: String): Unit fn clear(): Unit } // Browser navigation effect effect Navigation { fn pushState(url: String): Unit fn replaceState(url: String): Unit fn back(): Unit fn forward(): Unit fn getLocation(): String fn getPathname(): String } // Browser window effect effect Window { fn alert(message: String): Unit fn confirm(message: String): Bool fn scrollTo(x: Int, y: Int): Unit fn getInnerWidth(): Int fn getInnerHeight(): Int } // ============================================================================ // Subscription types for listening to external events // ============================================================================ type Sub = | OnAnimationFrame(fn(Float): M) | OnResize(fn(Int, Int): M) | OnKeyPress(fn(String): M) | OnKeyDown(fn(String): M) | OnKeyUp(fn(String): M) | OnMouseMove(fn(Int, Int): M) | OnClick(fn(Int, Int): M) | OnUrlChange(fn(String): M) | Every(Int, fn(Float): M) | NoSub // Subscription constructors fn onAnimationFrame(toMsg: fn(Float): M): Sub = OnAnimationFrame(toMsg) fn onResize(toMsg: fn(Int, Int): M): Sub = OnResize(toMsg) fn onKeyPress(toMsg: fn(String): M): Sub = OnKeyPress(toMsg) fn every(ms: Int, toMsg: fn(Float): M): Sub = Every(ms, toMsg) fn noSub(): Sub = NoSub // Combine multiple subscriptions fn batch(subs: List>): List> = subs