Achei até estranho não mencionar o distinctUntilChanged. Mas era challenge. Show! Optei por usar o debounceTime apenas depois do filter, uma vez que não importa a quantidade de tempo, ele só vai fazer a requisição quando a condição for verdadeira.
livrosEncontrados$ = this.campoBusca.valueChanges.pipe(
filter((valorDigitado) => valorDigitado.length > 3),
debounceTime(this.pauseBusca),
distinctUntilChanged(),
switchMap((valorDigitado) => this.service.buscar(valorDigitado)),
map((resultado) => this.obterResultadoLivros(resultado.items))
);