/**
 * Utilities related to reactivity that we're not quite ready to expose in the public API but which are useful for
 * internal component development.
 *
 * @experimental
 * @internal
 */

/**
 * @experimental
 * @internal
 */
export interface Signal<T> {
  value: T;
  /**
   * @param mutateFn
   * @experimental
   */
  mutate(mutateFn: (value: T) => void): void;
}

/**
 * @experimental
 * @internal
 */
export interface ReactiveObservable {
  /** @experimental */
  notify(): void;
}

/**
 * @experimental
 * @internal
 */
export interface ReactiveTrackingTarget {
  /** @experimental */
  clear(): void;
  /** @experimental */
  destroy(): void;
}

/**
 * @param initialValue
 * @param equalityFunction
 * @experimental
 * @internal
 */
export function signal<T>(initialValue: T, equalityFunction?: (a: T, b: T) => boolean): Signal<T>;

/**
 * @experimental
 * @internal
 */
export function createObservable(): ReactiveObservable;

/**
 * @param notify
 * @experimental
 * @internal
 */
export function createTrackingTarget(notify: () => void): ReactiveTrackingTarget;

/**
 * @param observable
 * @experimental
 * @internal
 */
export function trackAccess(observable: ReactiveObservable): void;

/**
 * @param target
 * @param callback
 * @experimental
 * @internal
 */
export function runTracked<T>(target: ReactiveTrackingTarget, callback: () => T): T | null;