UNPKG

micro-ftch

Version:

Wrappers for built-in fetch() enabling killswitch, logging, concurrency limit and other features

205 lines (203 loc) 7.21 kB
/** * Wrappers for [built-in fetch()](https://developer.mozilla.org/en-US/docs/Web/API/fetch) enabling * killswitch, logging, concurrency limit and other features. fetch is great, however, its usage in secure environments is complicated. The library makes it simple. * @module * @example ```js import { ftch, jsonrpc, replayable } from 'micro-ftch'; let enabled = false; const net = ftch(fetch, { isValidRequest: () => enabled, log: (url, options) => console.log(url, options), timeout: 5000, concurrencyLimit: 10, }); const res = await net('https://example.com'); // Composable const rpc = jsonrpc(net, 'http://rpc_node/', { headers: {}, batchSize: 20, }); const res1 = await rpc.call('method', 'arg0', 'arg1'); const res2 = await rpc.callNamed('method', { arg0: '0', arg1: '1' }); // named arguments const testRpc = replayable(rpc); // Basic auth auto-parsing await net('https://user:pwd@httpbin.org/basic-auth/user/pwd'); ``` */ declare function limit(concurrencyLimit: number): <T>(fn: () => Promise<T>) => Promise<T>; /** Arguments for built-in fetch, with added timeout method. */ export type FetchOpts = RequestInit & { timeout?: number; }; /** Built-in fetch, or function conforming to its interface. */ export type FetchFn = (url: string, opts?: FetchOpts) => Promise<{ headers: Headers; ok: boolean; redirected: boolean; status: number; statusText: string; type: ResponseType; url: string; json: () => Promise<any>; text: () => Promise<string>; arrayBuffer: () => Promise<ArrayBuffer>; }>; /** Options for `ftch`. isValidRequest can disable fetching, while log will receive all requests. */ export type FtchOpts = { isValidRequest?: (url?: string) => boolean; killswitch?: (url?: string) => boolean; concurrencyLimit?: number; timeout?: number; log?: (url: string, opts: FetchOpts) => void; }; /** * Small wrapper over fetch function * * @param fn - The fetch function to be wrapped. * @param opts - Options to control the behavior of the fetch wrapper. * @param [opts.isValidRequest] - Function to determine if the fetch request should be cancelled. * @param [opts.concurrencyLimit] - Limit on the number of concurrent fetch requests. * @param [opts.timeout] - Default timeout for all requests, can be overriden in request opts * @param [opts.log] - Callback to log all requests * @returns Wrapped fetch function * @example * ```js * let ENABLED = true; * const f = ftch(fetch, { isValidRequest: () => ENABLED }); * f('http://localhost'); // ok * ENABLED = false; * f('http://localhost'); // throws * ``` * @example * ```js * const f = ftch(fetch, { concurrencyLimit: 1 }); * const res = await Promise.all([f('http://url1/'), f('http://url2/')]); // these would be processed sequentially * ``` * @example * ```js * const f = ftch(fetch); * const res = await f('http://url/', { timeout: 1000 }); // throws if request takes more than one second * ``` * @example * ```js * const f = ftch(fetch, { timeout: 1000 }); // default timeout for all requests * const res = await f('http://url/'); // throws if request takes more than one second * ``` * @example * ```js * const f = ftch(fetch); * const res = await f('https://user:pwd@httpbin.org/basic-auth/user/pwd'); // basic auth * ``` * @example * ```js * const f = ftch(fetch, { log: (url, opts)=>console.log('NET', url, opts) }) * f('http://url/'); // will print request information * ``` */ export declare function ftch(fetchFunction: FetchFn, opts?: FtchOpts): FetchFn; export type JsonrpcInterface = { call: (method: string, ...args: any[]) => Promise<any>; callNamed: (method: string, args: Record<string, any>) => Promise<any>; }; type NetworkOpts = { batchSize?: number; headers?: Record<string, string>; }; /** * Small utility class for Jsonrpc * @param fetchFunction - The fetch function * @param url - The RPC server url * @param opts - Options to control the behavior of RPC client * @param [opts.headers] - additional headers to send with requests * @param [opts.batchSize] - batch parallel requests up to this value into single request * @example * ```js * const rpc = new JsonrpcProvider(fetch, 'http://rpc_node/', { headers: {}, batchSize: 20 }); * const res = await rpc.call('method', 'arg0', 'arg1'); * const res2 = await rpc.callNamed('method', {arg0: '0', arg1: '1'}); // named arguments * ``` */ export declare class JsonrpcProvider implements JsonrpcInterface { private batchSize; private headers; private queue; private fetchFunction; readonly rpcUrl: string; constructor(fetchFunction: FetchFn, rpcUrl: string, options?: NetworkOpts); private fetchJson; private jsonError; private batchProcess; private rpcBatch; private rpc; call(method: string, ...args: any[]): Promise<any>; callNamed(method: string, params: Record<string, any>): Promise<any>; } /** * Batched JSON-RPC functionality. * @example ```js const rpc = jsonrpc(fetch, 'http://rpc_node/', { headers: {}, batchSize: 20, }); const res = await rpc.call('method', 'arg0', 'arg1'); const res2 = await rpc.callNamed('method', { arg0: '0', arg1: '1' }); // named arguments ``` */ export declare function jsonrpc(fetchFunction: FetchFn, rpcUrl: string, options?: NetworkOpts): JsonrpcProvider; type GetKeyFn = (url: string, opt: FetchOpts) => string; /** Options for replayable() */ export type ReplayOpts = { offline?: boolean; getKey?: GetKeyFn; }; /** replayable() return function, additional methods */ export type ReplayFn = FetchFn & { logs: Record<string, any>; accessed: Set<string>; export: () => string; }; /** * Log & replay network requests without actually calling network code. * @param fetchFunction * @param logs - captured logs (JSON.parse(fetchReplay(...).export())) * @param opts * @param [opts.offline] - Offline mode, throws on non-captured requests * @param [opts.getKey] - Optional function to modify key information for capture/replay of requests * @example * ```js * // Capture logs * const ftch = ftch(fetch); * const replayCapture = replayable(ftch); // wraps fetch * await replayCapture('http://url/1'); * const logs = replayCapture.export(); // Exports logs * ``` * @example * ```js * // Replay logs * const replayTest = replayable(ftch, JSON.parse(logs)); * await replayTest('http://url/1'); // cached * await replayTest('http://url/2'); // real network * ``` * @example * ```js * // Offline mode * const replayTestOffline = replayable(ftch, JSON.parse(logs), { offline: true }); * await replayTest('http://url/1'); // cached * await replayTest('http://url/2'); // throws! * ``` * @example * ```js * // Custom log key function * const getKey = (url, opt) => JSON.stringify({ url: 'https://NODE_URL/', opt }); // use same url for any request * const replayCapture = replayable(ftch, {}, { getKey }); * ``` */ export declare function replayable(fetchFunction: FetchFn, logs?: Record<string, string>, opts?: ReplayOpts): ReplayFn; /** Internal methods for test purposes only. */ export declare const _TEST: { limit: typeof limit; }; export {}; //# sourceMappingURL=index.d.ts.map