@lialh4/effect-dom
v0.1.1
Published
Type-safe DOM manipulation with explicit, composable error handling.
Readme
Effect Dom
Type-safe DOM manipulation with explicit, composable error handling.
Stop wondering why querySelector returned null. Stop casting to types you're not sure about. Effect Dom makes DOM errors explicit but simple to handle. ✨
Why Effect Dom?
Explicit errors, zero surprises. DOM operations fail in predictable ways—selectors can be malformed, elements might not exist, or be the wrong type. Effect Dom surfaces all these errors in your types, while keeping the happy path clean.
The Problem 😰
// Runtime surprises waiting to happen
const audio = document.querySelector("#player") as HTMLAudioElement
audio.play() // 💥 What if it's null? What if it's a <div>?
// Or defensive programming everywhere...
const elem = document.querySelector("#player")
if (!elem) throw new Error("not found")
if (!(elem instanceof HTMLAudioElement)) throw new Error("wrong type")
audio.play()The Solution ✨
import { findElem } from "@lialh4/effect-dom/Elem"
import { Effect } from "effect"
const program = findElem(document, HTMLAudioElement, "#player").pipe(
Effect.andThen(audio => audio.play())
)
// ✅ All errors are typed and composable
// SelSyntaxError | ElemNotFoundError | ElemTypeMismatchErrorFeatures
✅ Type-Safe Queries – Get the exact element type you expect, or fail explicitly.
🔒 Cross-Origin Aware – Handle iframe documents safely with proper error types.
🔗 Composable – Chain operations naturally with Effect's pipe and error handling.
⚡ Zero Runtime Overhead – Thin wrapper over native DOM APIs.
Quick Example
import { Effect } from "effect"
import { findElem } from "@lialh4/effect-dom/Elem"
import { getInnerDoc } from "@lialh4/effect-dom/Doc"
// Find iframe → get its document → find element inside
const program = findElem(document, HTMLIFrameElement, "#my-iframe").pipe(
Effect.flatMap(getInnerDoc),
Effect.flatMap(findElem(HTMLButtonElement, ".submit")),
Effect.andThen(button => button.click())
)
// Handle all possible errors in one place 🎯
Effect.runPromise(program).catch(error => {
// SelSyntaxError | ElemNotFoundError | ElemTypeMismatchError | CrossOriginError
console.error(error._tag, error)
})Installation
bun add effect-domOr
pnpm install effect-domLicense
MIT
Changelog
0.1.0
First version! :tada:
0.1.1
Fix Example in readme.
