import { createEffect, untrack } from "solid-js";

/**
 * Fires `onChange(next, previous)` whenever the tracked value changes by
 * identity. Mirrors Base UI React's `useValueChanged`
 * (`packages/react/src/internals/useValueChanged.ts`).
 *
 * The value must be provided as a reactive accessor. In Solid 2, change
 * detection maps naturally to the split-effect form: the compute half returns
 * the current value, and the apply half receives both the new compute return
 * and the prior one. We carry a "first run" latch so the callback isn't
 * fired on initial setup (matching React — its first effect pass sees
 * `valueRef.current === value` because both came from the same render).
 *
 * The callback runs inside `untrack` so it can call into other accessors
 * (`field.shouldValidateOnChange()`, `name()`, etc.) without tripping
 * `[STRICT_READ_UNTRACKED]`. Side-effect callbacks read snapshots, they
 * don't subscribe — re-runs are driven by the tracked `value` accessor
 * passed as the first argument.
 *
 * @param value Accessor for the tracked value.
 * @param onChange Called with `(next, previous)` whenever `value()` changes.
 *                 Most callers ignore `previous` — accept it positionally if
 *                 you need to compare the transition.
 */
export function useValueChanged(value, onChange) {
  // Closure latch — flipped true after the effect's first apply so
  // subsequent runs fire `onChange`. Declared before `createEffect` so the
  // apply closure doesn't reference a let-binding that is textually below
  // its own declaration (TDZ-safe today because apply is async, but it's
  // fragile — keeping the declaration above is clearer).
  let primed = false;
  createEffect(
  // The compute phase just tracks `value()`; its return is also what
  // Solid forwards as `prev` on the next run.
  () => value(), (next, prev) => {
    // `prev` is undefined on the first run (Solid 2 split-effect
    // semantics). But `undefined` is a legitimate `T` value for some
    // callers, so we use a separate latch instead of checking `prev`.
    if (!primed) {
      primed = true;
      return;
    }
    if (!Object.is(next, prev)) {
      untrack(() => onChange(next, prev));
    }
  });
}
//# sourceMappingURL=use-value-changed.jsx.map
