import { D as DelegateOptions } from './delegate-CL9VTZFb.js'; import { M as MountResult } from './mount-Bo2qOx25.js'; import './jsx-runtime.js'; import '@preact/signals-core'; import './bindings-CYwoJpQb.js'; /** * `kerfjs/scope` — tie a set of disposers to a DOM element's lifetime. * * kerf hands out disposers (`mount()` / `effect()` / `delegate()` all return * `() => void`), but nothing scopes them to a subtree's lifetime — so an * append-heavy app (a feed, a list of cards) leaks detached-but-subscribed * effects, listeners, and observers. Every such app hand-rolls the same * `WeakMap` swept on removal. This subpath blesses it. * * import { disposeScope, disposeSubtree, observeRemovals } from 'kerfjs/scope'; * * const s = disposeScope(card); * s.mount(card, renderCard); // mounts AND registers its disposer * s.effect(() => syncCard(card)); * s.delegate(card, 'click', '.del', del); * s.add(() => observer.disconnect()); // any () => void disposer * // …when the card goes away: * disposeSubtree(feed); // runs every scope in feed (incl. feed) * feed.remove(); * * Or install one observer and let removals auto-dispose: * observeRemovals(document.body); * * No module-level mutable state: scopes live in a `WeakMap` (GC-tied, keyed by * element), and `disposeSubtree` finds them by walking the subtree. */ /** A per-element teardown scope. Calling `disposeScope(el)` again returns the SAME scope. */ interface Scope { /** Register any `() => void` disposer (a `mount`/`effect`/`delegate` return, a listener remover, …). Returns it. */ add(dispose: () => void): () => void; /** `mount()` into `el` and register its disposer in one step. Returns the disposer. */ mount(el: HTMLElement, render: () => MountResult): () => void; /** `effect(fn)` and register its disposer in one step. Returns the disposer. */ effect(fn: () => void | (() => void)): () => void; /** `delegate(...)` and register its disposer in one step. Returns the disposer. */ delegate(root: HTMLElement, type: string, selector: string, handler: (event: Event, target: T) => void, options?: DelegateOptions): () => void; /** Run every registered disposer (best-effort — a throwing one won't strand the rest) and reset. Idempotent. */ dispose(): void; } /** * Get (or create) the teardown {@link Scope} for `el`. Repeated calls for the * same element return the same scope, so disparate code paths can register into * one place. After `dispose()`, a later `disposeScope(el)` starts fresh. */ declare function disposeScope(el: Element): Scope; /** * Dispose every scope within `root` (including `root`'s own), then leave the DOM * to you. Call it right before removing a subtree. Finds scopes by walking the * subtree against the `WeakMap` — no marker attributes are added to your DOM. */ declare function disposeSubtree(root: Element): void; /** * Install a `MutationObserver` on `root` that auto-disposes a node's scope when * that node (or an ancestor) is removed from the subtree. One observer covers * the whole tree. Returns a disconnect function. Note: `MutationObserver` fires * asynchronously, so disposal runs a microtask after the removal. */ declare function observeRemovals(root: Element): () => void; export { type Scope, disposeScope, disposeSubtree, observeRemovals };