Skip to content

Client and registration ​

Create a Fetcher for shared URL, headers, timeout, and interceptor policy. Requests use the runtime's global fetch unless the fetch option supplies another; a client does not own a connection pool or require destroy().

Construction and defaults ​

new Fetcher(options?: FetcherOptions) accepts the following options. Supplying an options object requires baseURL; omitting the object uses DEFAULT_OPTIONS.

OptionDefaultContract
baseURL: string''Used by the mutable urlBuilder; relative URLs still need a runtime that accepts them.
headers?: RequestHeaders{}No Content-Type by default; the body interceptor sets it from the body. The client keeps its own copy of a supplied object. Each request gets a defensive, case-insensitive merge.
timeout?: numberundefinedMilliseconds; no timer until configured. Request 0 disables the inherited timeout.
urlTemplateStyle?UrlTemplateStyle.UriTemplate{id} syntax; Express selects :id.
interceptors?New InterceptorManagerSupplied manager is used as-is; it can be shared across clients.
validateStatus?200 <= status < 300Used only when constructing the default manager.
fetch?: FetchImplementation (type)Global fetch, read at call timeThe fetch that sends requests, for a runtime or framework that supplies its own (Tauri, instrumentation) or a test. Timeouts and signals still apply. Like validateStatus, used only when constructing the default manager.

urlBuilder, headers, and timeout can be changed for subsequent requests. interceptors is readonly as a property, while its registries remain mutable. Each client owns a copy of its headers, so mutating client.headers affects only that client; mutating exported DEFAULT_OPTIONS.headers still changes every client created afterwards, so use request headers instead.

Choosing an entry point ​

MethodInputResolved value without an explicit extractor
resolveExchange(request, options?)FetchRequest, RequestOptionsA synchronous FetchExchange; no HTTP I/O.
exchange(request, options?)SamePromise<FetchExchange> after the interceptor pipeline; does not extract a body.
request<R = FetchExchange>(request, options?)SamePromise<R> through the selected extractor; default exchange.
fetch<R = Response>(url, request = {}, options?)FetchRequestInitPromise<R>; default native Response.
get, head, options, traceURL, request without method/body, optionsPromise<R = Response>; method fixed by the helper.
post, put, patch, deleteURL, request without method, optionsSame, with optional body.

DEFAULT_REQUEST_OPTIONS selects ResultExtractors.Exchange; DEFAULT_FETCH_OPTIONS selects ResultExtractors.Response. A generic such as get<User>() alone does not parse JSON: select an extractor or call response.json<User>(). Native Fetch may reject unsupported methods such as TRACE. See results and errors.

Named clients ​

new NamedFetcher(name, options?) extends Fetcher and immediately registers itself in the singleton fetcherRegistrar, which lives on globalThis so a second copy of the package in the same process (its ESM and CommonJS builds, or two versions) shares it. fetcher is the exported default named instance, with DEFAULT_FETCHER_NAME = 'default'; a second copy reuses the default already registered instead of replacing it. Duplicate registration replaces the prior client.

FetcherRegistrar.register(name, client): void, unregister(name): boolean, and get(name): Fetcher | undefined manage entries. requiredGet(name) and the default getter throw Error when absent. Assigning default registers under 'default'; fetchers returns a new Map whose values are the same clients. Unregistering does not abort in-flight requests.

getFetcher(fetcher?, defaultFetcher?) accepts a direct instance, a registry name, or no value. A string is a name and must exist; any other value is used as the fetcher (no instanceof check, so a fetcher from another copy of the package works); a falsy argument chooses the supplied fallback and then the global default. FetcherCapable exposes that optional field. NamedCapable supplies name, and FetcherConfigurer.applyTo(fetcher): void is the structural contract used by configurable extensions.

Complete example ​

ts
import {
  Fetcher,
  NamedFetcher,
  fetcherRegistrar,
  getFetcher,
} from '@ahoo-wang/fetcher';

const local = new Fetcher({
  baseURL: 'https://api.example.com',
  timeout: 3000,
});
const named = new NamedFetcher('reports', {
  baseURL: 'https://reports.example.com',
});
console.assert(getFetcher('reports') === named);
const exchange = local.resolveExchange({ url: '/users/1' });
console.assert(exchange.request.timeout === 3000);
fetcherRegistrar.unregister('reports');

Public symbols and source ​

SymbolImplementation
FetcherOptionsfetcher.ts:57
DEFAULT_OPTIONSfetcher.ts:105
RequestOptionsrequestOptions.ts:21
DEFAULT_REQUEST_OPTIONSrequestOptions.ts:25
DEFAULT_FETCH_OPTIONSrequestOptions.ts:30
Fetcherfetcher.ts:129
FetcherCapablefetcherCapable.ts:22
getFetcherfetcherCapable.ts:37
DEFAULT_FETCHER_NAMEfetcherRegistrar.ts:19
FetcherRegistrarfetcherRegistrar.ts:41
fetcherRegistrarfetcherRegistrar.ts:172
NamedFetchernamedFetcher.ts:38
fetchernamedFetcher.ts:94
NamedCapabletypes.ts:141
FetcherConfigurerfetcherConfigurer.ts:39

Package index

Released under the Apache License 2.0.