Instead of having multiple adhoc listeners that catch their specific event to run async work or stream processor.
We could have a generic source event producer, which is a sync listener of source event in a transaction, this listener is enlisted to the transaction and will output events to a source event stream. (same principle as the StreamAuditEventListener)
This could be used for extracting fulltext (instead of doing it during session.flush), indexing, ml pipeline, whatever processing.
The hardest part is to find source event that should represent user's action rather than recording the effect of those actions.