/** * Component-scoped reactive primitives. * * Provides `useSignal`, `useComputed`, and `useEffect` that automatically * dispose when their owning component disconnects from the DOM. * * @module bquery/component */ import type { Computed } from '../reactive/computed'; import type { Signal } from '../reactive/core'; import type { CleanupFn } from '../reactive/index'; /** * Holds disposable resources created inside a component scope. * All registered disposers run when the component disconnects. * @internal */ export interface ComponentScope { /** Register a cleanup function to run on dispose */ addDisposer(fn: CleanupFn): void; /** Dispose all registered resources */ dispose(): void; } /** * Sets the active component scope. * @internal */ export declare function setCurrentScope(scope: ComponentScope | undefined): ComponentScope | undefined; /** * Returns the active component scope, or undefined if none. * @internal */ export declare function getCurrentScope(): ComponentScope | undefined; /** * Creates a new component scope that tracks disposable resources. * @internal */ export declare function createComponentScope(): ComponentScope; /** * Creates a reactive signal scoped to the current component. * * The signal is automatically disposed when the component disconnects * from the DOM, removing all subscribers and preventing memory leaks. * * Must be called during a component lifecycle hook such as `connected`, * `beforeMount`, `onAdopted`, or `onAttributeChanged`. * * Do not create scoped primitives from `render()`. Repeated renders can * accumulate render-scoped resources until disconnect; prefer lifecycle hooks. * * @template T - The type of the signal value * @param initialValue - The initial value of the signal * @returns A new Signal instance that auto-disposes with the component * @throws {Error} If called outside a component scope * * @example * ```ts * import { component, html, useSignal } from '@bquery/bquery/component'; * * component('my-counter', { * connected() { * const count = useSignal(0); * // count.dispose() is called automatically on disconnect * }, * render({ state }) { * return html`${state.count}`; * }, * }); * ``` */ export declare function useSignal(initialValue: T): Signal; /** * Creates a computed value scoped to the current component. * * The computed value's internal effect is automatically cleaned up * when the component disconnects from the DOM. * * Must be called during a component lifecycle hook such as `connected`, * `beforeMount`, `onAdopted`, or `onAttributeChanged`. * * Do not create scoped primitives from `render()`. Repeated renders can * accumulate render-scoped resources until disconnect; prefer lifecycle hooks. * * @template T - The type of the computed value * @param fn - Derivation function that reads reactive sources * @returns A new Computed instance that auto-cleans-up with the component * @throws {Error} If called outside a component scope * * @example * ```ts * import { component, html, useSignal, useComputed } from '@bquery/bquery/component'; * * component('my-doubler', { * connected() { * const count = useSignal(1); * const doubled = useComputed(() => count.value * 2); * }, * render({ state }) { * return html`${state.doubled}`; * }, * }); * ``` */ export declare function useComputed(fn: () => T): Computed; /** * Creates a side effect scoped to the current component. * * The effect runs immediately and re-runs when its reactive dependencies * change. It is automatically disposed when the component disconnects * from the DOM. * * Must be called during a component lifecycle hook such as `connected`, * `beforeMount`, `onAdopted`, or `onAttributeChanged`. * * Do not create scoped primitives from `render()`. Repeated renders can * accumulate render-scoped resources until disconnect; prefer lifecycle hooks. * * @param fn - The effect function; may return a cleanup function * @returns A cleanup function to manually stop the effect early * @throws {Error} If called outside a component scope * * @example * ```ts * import { component, useSignal, useEffect } from '@bquery/bquery/component'; * * component('my-logger', { * connected() { * const count = useSignal(0); * useEffect(() => { * console.log('Count changed:', count.value); * return () => console.log('Cleanup'); * }); * }, * render() { return '

Logger

'; }, * }); * ``` */ export declare function useEffect(fn: () => void | CleanupFn): CleanupFn; //# sourceMappingURL=scope.d.ts.map