### Description

Add listeners for Datasets (events)

### Use case/motivation

As Airflow administrators, we would like to trigger some external processes based on all datasets being created/updated by our users. We came across the listeners for the dag runs and task instances (which are also useful), but are still missing listeners for datasets.

### Related issues

_No response_

### Are you willing to submit a PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

dag_ids: list[str], *, session: Session
) -> dict[str, dict[str, int | str]]:
    """
    Get next run info for a list of dag_ids.
    Given a list of dag_ids, get string representing how close any that are dataset triggered are
    their next run, e.g. "1 of 2 datasets updated".
    """
    from airflow.models.dataset import DagScheduleDatasetReference, DatasetDagRunQueue as DDRQ, DatasetModel
    return {
        x.dag_id: {
            "uri": x.uri,
            "ready": x.ready,
            "total": x.total,
        }
        for x in session.execute(
            select(
                DagScheduleDatasetReference.dag_id,
                
                
                case((func.count() == 1, func.max(DatasetModel.uri)), else_="").label("uri"),
                func.count().label("total"),
                func.sum(case((DDRQ.target_dag_id.is_not(None), 1), else_=0)).label("ready"),
            )
            .join(
                DDRQ,
                and_(
                    DDRQ.dataset_id == DagScheduleDatasetReference.dataset_id,
                    DDRQ.target_dag_id == DagScheduleDatasetReference.dag_id,
                ),