abort-previous
Whenever a new request starts, the previous in-flight one from the same client is aborted. The search-as-you-type primitive. Being stateful it's client-level; see the Plugins overview for how plugins are applied.
ts
import { corgi } from '@itsy/corgi';
import { abortPrevious } from '@itsy/corgi/abort-previous';
const search = corgi.create({ plugins: [abortPrevious()] });
// Each keystroke supersedes the last; the abandoned request rejects with AbortError.
async function onType(q: string) {
try {
return await search.get('/search', { query: { q } });
} catch (err) {
// In typeahead you normally ignore the expected AbortError.
}
}How it works
- Tagged
ORDER.cancel(the outermost slot), so a superseding call cancels the entire prior chain, including any retries or timeout it had running. - Keyless by design: one plugin instance is one logical stream (e.g. one search box). Create separate clients for separate streams.
- A fresh
AbortControlleris minted per call, so cancellation keeps working indefinitely. Reusing a single controller would leave it "aborted" forever after the first cancel. - The caller's own
signalis merged in, so your own aborts still work.
It's stateful, so keep it client-level
abortPrevious stores the current request in a closure created when the client's pipeline is built. That's why it must live at the client level:
ts
const search = corgi.create({ plugins: [abortPrevious(), withTimeout(5000)] });On the server
Because it holds state, build the client per request on a server. Never share one at module scope, or unrelated requests would cancel each other.