That you consider such a task, that should range from 1.5 to 2k of client-side scraping to be a "huge endeavor" or "horrendous to write tests for" says a lot to me... but then with the whole "obersvable" nonsense in the mix alongside the "latest value not the same" thing, you're likely about a decade behind on coding practices.
I'm not saying that for certain, and it's not meant as an insult, it's just what it sounds like...
what with the "input" event only firing when an input that would change the value is done, the delay is easy-peasy as is XMLHttpRequest.abort()... and 90% of the HTML and content gruntwork handled by <datalist>
I mean put a datalist after the input in the markup, grab all the input by use querySelectorAll assigning data- attributes containing the URI to pull from. Grab the associated input, "abuse" data- to store the associated list, timeout handler, and request object, and assign the input event listener.
Said listener would pull the input by event.currentTarget, check if data-timeout is set and if so clear it. Check if the request is ongoing, if so abort it and null data-request, then set a new timeout to start the request loader.
Said loader nulling data-timeout, if the input value is empty delete all <option> in the datalist and short-circuit out. Otherwise make a formData containing the input name and value, put a reference to the <datalist> on the request (HMLHTtpRequest) object so we don't have to play games with oddball wrapping trash, hook the loadend event, POST the request with making sure the mime-type is set in a way that prevents the default XML parse.
The loadend event's handler simply grabbing the request off of event.currentTarget, I'd probably use the ASCII unit selector to split the data up that way we can be even simpler than stuff like JSON. STrip out all the existing OPTION, create new OPTION where value == ecah line of the response...
Done. That would/should be around 1.5k, add a "error" event and some status checking and you're looking at 2k of relatively bulletproof code. Especially if you put it in a IIFE since this is client-side and modules/includes tend to be trash for that.
Not rocket science.
And part of why most of the off the shelf answers seem to be trash, either from a lack of proper error handling thanks to that promise junk with zero error handling, not leveraging <datalist> and instead talking some sort of "component" bloat, endless tricks to try and keep track of stuff that could just be stored on the DOM, often hardcoded to a single input instead of proving multi-input capability, and worst of all?
MOST off the shelf framework implementations don't leave you with a working / functional input/form if scripting is off/disabled/irrelevant.
Though thank you very much, when/if I write the code for what I describe above, it might make for a decent article.
oh, also after the first letter if you populate datalist you could probably skip any further queries... though I'd probably not query until the user has at least two letters present. That's the magic of datalist doing almost all your heavy lifting for you, and making a LOT of the stuff people throw scripting at these days very pointless.