import { type Cleanup, type SignalOptions } from '../graph';
/**
 * A read-only signal that tracks external input and updates a state value as long as it is active.
 *
 * @template T - The type of value produced by the sensor
 */
type Sensor<T extends {}> = {
    readonly [Symbol.toStringTag]: 'Sensor';
    /**
     * Gets the current value of the sensor.
     * When called inside another reactive context, creates a dependency.
     * @returns The sensor value
     * @throws UnsetSignalValueError If the sensor value is still unset when read.
     */
    get(): T;
};
/**
 * Configuration options for `createSensor`.
 *
 * @template T - The type of value produced by the sensor
 */
type SensorOptions<T extends {}> = SignalOptions<T> & {
    /**
     * Optional initial value. Avoids `UnsetSignalValueError` on first read
     * before the watched callback fires.
     */
    value?: T;
};
/**
 * Setup callback for `createSensor`. Invoked when the sensor gains its first downstream
 * subscriber; receives a `set` function to push new values into the graph.
 *
 * @template T - The type of value produced by the sensor
 * @param set - Updates the sensor value and propagates the change to subscribers
 * @returns A cleanup function invoked when the sensor loses all subscribers
 */
type SensorCallback<T extends {}> = (set: (next: T) => void) => Cleanup;
/**
 * Creates a sensor that tracks external input and updates a state value as long as it is active.
 * Sensors get activated when they are first accessed by an effect and deactivated when they are
 * no longer watched. This lazy activation pattern ensures resources are only consumed when needed.
 *
 * @since 0.18.0
 * @template T - The type of value produced by the sensor
 * @param watched - The callback invoked when the sensor starts being watched, receives a `set` function and returns a cleanup function.
 * @param options - Optional configuration for the sensor.
 * @param options.value - Optional initial value. Avoids `UnsetSignalValueError` on first read
 *   before the watched callback fires. Essential for the mutable-object observation pattern.
 * @param options.equals - Optional equality function. Defaults to strict equality (`===`). Use `SKIP_EQUALITY`
 *   for mutable objects where the reference stays the same but internal state changes.
 * @param options.guard - Optional type guard to validate values.
 * @returns A read-only sensor signal.
 *
 * @example Tracking external values
 * ```ts
 * const mousePos = createSensor<{ x: number; y: number }>((set) => {
 *   const handler = (e: MouseEvent) => {
 *     set({ x: e.clientX, y: e.clientY });
 *   };
 *   window.addEventListener('mousemove', handler);
 *   return () => window.removeEventListener('mousemove', handler);
 * });
 * ```
 *
 * @example Observing a mutable object
 * ```ts
 * import { createSensor, SKIP_EQUALITY } from 'cause-effect';
 *
 * const el = createSensor<HTMLElement>((set) => {
 *   const node = document.getElementById('box')!;
 *   set(node);
 *   const obs = new MutationObserver(() => set(node));
 *   obs.observe(node, { attributes: true });
 *   return () => obs.disconnect();
 * }, { value: node, equals: SKIP_EQUALITY });
 * ```
 */
declare function createSensor<T extends {}>(watched: SensorCallback<T>, options?: SensorOptions<T>): Sensor<T>;
/**
 * Checks if a value is a Sensor signal.
 *
 * @since 0.18.0
 * @param value - The value to check
 * @returns True if the value is a Sensor
 */
declare function isSensor<T extends {} = unknown & {}>(value: unknown): value is Sensor<T>;
export { createSensor, isSensor, type Sensor, type SensorCallback, type SensorOptions, };
