diff --git a/.api-reports/api-report-link_batch.api.md b/.api-reports/api-report-link_batch.api.md index c1413d1b607..d7ba2b71bd2 100644 --- a/.api-reports/api-report-link_batch.api.md +++ b/.api-reports/api-report-link_batch.api.md @@ -5,25 +5,16 @@ ```ts import { ApolloLink } from '@apollo/client/link'; -import { Observable } from 'rxjs'; - -// @public (undocumented) -export interface BatchableRequest { - // (undocumented) - forward: ApolloLink.ForwardFunction; - // (undocumented) - operation: ApolloLink.Operation; -} - -// @public (undocumented) -export type BatchHandler = (operations: ApolloLink.Operation[], forward: ApolloLink.ForwardFunction[]) => Observable; +import type { Observable } from 'rxjs'; // @public (undocumented) export namespace BatchLink { + // (undocumented) + export type BatchHandler = (operations: ApolloLink.Operation[], forward: ApolloLink.ForwardFunction[]) => Observable; // (undocumented) export interface Options { batchDebounce?: boolean; - batchHandler?: BatchHandler; + batchHandler?: BatchLink.BatchHandler; batchInterval?: number; batchKey?: (operation: ApolloLink.Operation) => string; batchMax?: number; @@ -37,21 +28,6 @@ export class BatchLink extends ApolloLink { request(operation: ApolloLink.Operation, forward: ApolloLink.ForwardFunction): Observable; } -// @public (undocumented) -export class OperationBatcher { - constructor({ batchDebounce, batchInterval, batchMax, batchHandler, batchKey, }: { - batchDebounce?: boolean; - batchInterval?: number; - batchMax?: number; - batchHandler: BatchHandler; - batchKey?: (operation: ApolloLink.Operation) => string; - }); - // (undocumented) - consumeQueue(key?: string): (Observable | undefined)[] | undefined; - // (undocumented) - enqueueRequest(request: BatchableRequest): Observable; -} - // (No @packageDocumentation comment for this package) ``` diff --git a/.api-reports/api-report-link_error.api.md b/.api-reports/api-report-link_error.api.md index 12b293ada76..39f5baa2e14 100644 --- a/.api-reports/api-report-link_error.api.md +++ b/.api-reports/api-report-link_error.api.md @@ -8,11 +8,6 @@ import { ApolloLink } from '@apollo/client/link'; import type { ErrorLike } from '@apollo/client'; import { Observable } from 'rxjs'; -export interface ErrorHandler { - // (undocumented) - (options: ErrorHandlerOptions): Observable | void; -} - // @public (undocumented) export namespace ErrorLink { export interface ErrorHandler { @@ -34,7 +29,7 @@ export class ErrorLink extends ApolloLink { } // @public @deprecated (undocumented) -export function onError(errorHandler: ErrorHandler): ErrorLink; +export function onError(errorHandler: ErrorLink.ErrorHandler): ErrorLink; // (No @packageDocumentation comment for this package) diff --git a/.api-reports/api-report-link_persisted-queries.api.md b/.api-reports/api-report-link_persisted-queries.api.md index 20ab276aa07..5f45237ce8c 100644 --- a/.api-reports/api-report-link_persisted-queries.api.md +++ b/.api-reports/api-report-link_persisted-queries.api.md @@ -9,70 +9,63 @@ import type { DocumentNode } from 'graphql'; import type { ErrorLike } from '@apollo/client'; import type { FormattedExecutionResult } from 'graphql'; -// @public (undocumented) -interface BaseOptions { - // (undocumented) - disable?: (options: PersistedQueryLink.DisableFunctionOptions) => boolean; - // (undocumented) - retry?: (options: PersistedQueryLink.RetryFunctionOptions) => boolean; - // (undocumented) - useGETForHashedQueries?: boolean; -} - // @public @deprecated (undocumented) export const createPersistedQueryLink: (options: PersistedQueryLink.Options) => PersistedQueryLink; -// @public (undocumented) -type ErrorMeta = { - persistedQueryNotSupported: boolean; - persistedQueryNotFound: boolean; -}; - -// @public (undocumented) -type GenerateHashFunction = (document: DocumentNode) => string | PromiseLike; - // @public (undocumented) export namespace PersistedQueryLink { // (undocumented) - export interface CallbackOptions { - // (undocumented) - error: ErrorLike; - // Warning: (ae-forgotten-export) The symbol "ErrorMeta" needs to be exported by the entry point index.d.ts - // + export namespace Base { // (undocumented) - meta: ErrorMeta; + export interface Options { + // (undocumented) + disable?: (options: PersistedQueryLink.DisableFunctionOptions) => boolean; + // (undocumented) + retry?: (options: PersistedQueryLink.RetryFunctionOptions) => boolean; + // (undocumented) + useGETForHashedQueries?: boolean; + } + } + // (undocumented) + export interface DisableFunctionOptions extends PersistedQueryLink.RetryFunctionOptions { + } + // (undocumented) + export interface ErrorMeta { // (undocumented) - operation: ApolloLink.Operation; + persistedQueryNotFound: boolean; // (undocumented) - result?: FormattedExecutionResult; + persistedQueryNotSupported: boolean; } // (undocumented) - export interface DisableFunctionOptions extends CallbackOptions { - } + export type GenerateHashFunction = (document: DocumentNode) => string | PromiseLike; // (undocumented) - export interface GenerateHashOptions extends BaseOptions { - // Warning: (ae-forgotten-export) The symbol "GenerateHashFunction" needs to be exported by the entry point index.d.ts - // + export interface GenerateHashOptions extends Base.Options { // (undocumented) - generateHash: GenerateHashFunction; + generateHash: PersistedQueryLink.GenerateHashFunction; // (undocumented) sha256?: never; } // (undocumented) - export type Options = SHA256Options | GenerateHashOptions; + export type Options = PersistedQueryLink.SHA256Options | PersistedQueryLink.GenerateHashOptions; // (undocumented) - export interface RetryFunctionOptions extends CallbackOptions { + export interface RetryFunctionOptions { + // (undocumented) + error: ErrorLike; + // (undocumented) + meta: PersistedQueryLink.ErrorMeta; + // (undocumented) + operation: ApolloLink.Operation; + // (undocumented) + result?: FormattedExecutionResult; } - // Warning: (ae-forgotten-export) The symbol "BaseOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) - export interface SHA256Options extends BaseOptions { + export type SHA256Function = (queryString: string) => string | PromiseLike; + // (undocumented) + export interface SHA256Options extends Base.Options { // (undocumented) generateHash?: never; - // Warning: (ae-forgotten-export) The symbol "SHA256Function" needs to be exported by the entry point index.d.ts - // // (undocumented) - sha256: SHA256Function; + sha256: PersistedQueryLink.SHA256Function; } } @@ -83,9 +76,6 @@ export class PersistedQueryLink extends ApolloLink { resetHashCache: () => void; } -// @public (undocumented) -type SHA256Function = (...args: any[]) => string | PromiseLike; - // @public (undocumented) export const VERSION = 1; diff --git a/.api-reports/api-report-link_remove-typename.api.md b/.api-reports/api-report-link_remove-typename.api.md index a84d094617a..fc36249eba3 100644 --- a/.api-reports/api-report-link_remove-typename.api.md +++ b/.api-reports/api-report-link_remove-typename.api.md @@ -9,26 +9,26 @@ import { ApolloLink } from '@apollo/client/link'; // @public (undocumented) export const KEEP = "__KEEP"; -// @public (undocumented) -interface KeepTypenameConfig { - // (undocumented) - [key: string]: typeof KEEP | KeepTypenameConfig; -} - // @public @deprecated (undocumented) -export function removeTypenameFromVariables(options?: RemoveTypenameFromVariablesOptions): RemoveTypenameFromVariablesLink; +export function removeTypenameFromVariables(options?: RemoveTypenameFromVariablesLink.Options): RemoveTypenameFromVariablesLink; // @public (undocumented) -export class RemoveTypenameFromVariablesLink extends ApolloLink { - constructor(options?: RemoveTypenameFromVariablesOptions); +export namespace RemoveTypenameFromVariablesLink { + // (undocumented) + export interface KeepTypenameConfig { + // (undocumented) + [key: string]: typeof KEEP | RemoveTypenameFromVariablesLink.KeepTypenameConfig; + } + // (undocumented) + export interface Options { + // (undocumented) + except?: RemoveTypenameFromVariablesLink.KeepTypenameConfig; + } } // @public (undocumented) -export interface RemoveTypenameFromVariablesOptions { - // Warning: (ae-forgotten-export) The symbol "KeepTypenameConfig" needs to be exported by the entry point index.d.ts - // - // (undocumented) - except?: KeepTypenameConfig; +export class RemoveTypenameFromVariablesLink extends ApolloLink { + constructor(options?: RemoveTypenameFromVariablesLink.Options); } // (No @packageDocumentation comment for this package) diff --git a/.api-reports/api-report-link_retry.api.md b/.api-reports/api-report-link_retry.api.md index e7a9fb04f43..61ef8568bb7 100644 --- a/.api-reports/api-report-link_retry.api.md +++ b/.api-reports/api-report-link_retry.api.md @@ -7,41 +7,27 @@ import { ApolloLink } from '@apollo/client/link'; import { Observable } from 'rxjs'; -// @public -interface DelayFunction { - // (undocumented) - (count: number, operation: ApolloLink.Operation, error: any): number; -} - -// @public (undocumented) -interface DelayFunctionOptions { - initial?: number; - jitter?: boolean; - max?: number; -} - -// @public -interface RetryFunction { - // (undocumented) - (count: number, operation: ApolloLink.Operation, error: any): boolean | Promise; -} - -// @public (undocumented) -interface RetryFunctionOptions { - max?: number; - retryIf?: (error: any, operation: ApolloLink.Operation) => boolean | Promise; -} - // @public (undocumented) export namespace RetryLink { + // (undocumented) + export type AttemptsFunction = (count: number, operation: ApolloLink.Operation, error: any) => boolean | Promise; + // (undocumented) + export interface AttemptsOptions { + max?: number; + retryIf?: (error: any, operation: ApolloLink.Operation) => boolean | Promise; + } + // (undocumented) + export type DelayFunction = (count: number, operation: ApolloLink.Operation, error: any) => number; + // (undocumented) + export interface DelayOptions { + initial?: number; + jitter?: boolean; + max?: number; + } // (undocumented) export interface Options { - // Warning: (ae-forgotten-export) The symbol "RetryFunctionOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "RetryFunction" needs to be exported by the entry point index.d.ts - attempts?: RetryFunctionOptions | RetryFunction; - // Warning: (ae-forgotten-export) The symbol "DelayFunctionOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "DelayFunction" needs to be exported by the entry point index.d.ts - delay?: DelayFunctionOptions | DelayFunction; + attempts?: RetryLink.AttemptsOptions | RetryLink.AttemptsFunction; + delay?: RetryLink.DelayOptions | RetryLink.DelayFunction; } } diff --git a/.api-reports/api-report-link_schema.api.md b/.api-reports/api-report-link_schema.api.md index 8b942deac61..9beafc4c4ac 100644 --- a/.api-reports/api-report-link_schema.api.md +++ b/.api-reports/api-report-link_schema.api.md @@ -12,7 +12,7 @@ import { Observable } from 'rxjs'; export namespace SchemaLink { // (undocumented) export interface Options { - context?: ResolverContext | ResolverContextFunction; + context?: SchemaLink.ResolverContext | SchemaLink.ResolverContextFunction; rootValue?: any; schema: GraphQLSchema; validate?: boolean; diff --git a/.changeset/sharp-lemons-bathe.md b/.changeset/sharp-lemons-bathe.md new file mode 100644 index 00000000000..46a44a9e42d --- /dev/null +++ b/.changeset/sharp-lemons-bathe.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": major +--- + +Move all 1st party link types into a namespace. diff --git a/.changeset/sour-wombats-shout.md b/.changeset/sour-wombats-shout.md new file mode 100644 index 00000000000..e455d114e50 --- /dev/null +++ b/.changeset/sour-wombats-shout.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": major +--- + +The `OperationBatcher` class is no longer exported from `@apollo/client/link/batch`. It is an implementation detail of `BatchLink` and should not be relied on directly. diff --git a/.changeset/tough-hairs-develop.md b/.changeset/tough-hairs-develop.md new file mode 100644 index 00000000000..68d21ea6d0b --- /dev/null +++ b/.changeset/tough-hairs-develop.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Fix the type of the argument for the `sha256` function for `PersistedQueryLink` from `...any[]` to `string`. diff --git a/src/__tests__/__snapshots__/exports.ts.snap b/src/__tests__/__snapshots__/exports.ts.snap index 43841e8f502..0209b48e809 100644 --- a/src/__tests__/__snapshots__/exports.ts.snap +++ b/src/__tests__/__snapshots__/exports.ts.snap @@ -163,7 +163,6 @@ Array [ exports[`exports of public entry points @apollo/client/link/batch 1`] = ` Array [ "BatchLink", - "OperationBatcher", ] `; diff --git a/src/link/batch-http/batchHttpLink.ts b/src/link/batch-http/batchHttpLink.ts index c3501f9e9b6..42affb2233b 100644 --- a/src/link/batch-http/batchHttpLink.ts +++ b/src/link/batch-http/batchHttpLink.ts @@ -1,7 +1,6 @@ import { Observable, throwError } from "rxjs"; import { ApolloLink } from "@apollo/client/link"; -import type { BatchHandler } from "@apollo/client/link/batch"; import { BatchLink } from "@apollo/client/link/batch"; import { ClientAwarenessLink } from "@apollo/client/link/client-awareness"; import type { HttpLink } from "@apollo/client/link/http"; @@ -87,7 +86,7 @@ export class BaseBatchHttpLink extends ApolloLink { this.batchInterval = batchInterval || 10; this.batchMax = batchMax || 10; - const batchHandler: BatchHandler = (operations) => { + const batchHandler: BatchLink.BatchHandler = (operations) => { const chosenURI = selectURI(operations[0], uri); const context = operations[0].getContext(); diff --git a/src/link/batch/__tests__/batchLink.ts b/src/link/batch/__tests__/batchLink.ts index 46fa0f19bac..8e69d87b4f1 100644 --- a/src/link/batch/__tests__/batchLink.ts +++ b/src/link/batch/__tests__/batchLink.ts @@ -4,14 +4,17 @@ import { gql } from "graphql-tag"; import { EMPTY, map, Observable, of } from "rxjs"; import { ApolloLink } from "@apollo/client/link"; -import { BatchLink, OperationBatcher } from "@apollo/client/link/batch"; +import { BatchLink } from "@apollo/client/link/batch"; import { executeWithDefaultContext as execute, ObservableStream, wait, } from "@apollo/client/testing/internal"; -import type { BatchableRequest, BatchHandler } from "../batchLink.js"; +import type { BatchableRequest } from "../batching.js"; +// not exported +// eslint-disable-next-line local-rules/no-relative-imports +import { OperationBatcher } from "../batching.js"; interface MockedResponse { request: ApolloLink.Request; @@ -63,7 +66,7 @@ function requestToKey(request: ApolloLink.Request): string { function createMockBatchHandler(...mockedResponses: MockedResponse[]) { const mockedResponsesByKey: { [key: string]: MockedResponse[] } = {}; - const mockBatchHandler: BatchHandler = ( + const mockBatchHandler: BatchLink.BatchHandler = ( operations: ApolloLink.Operation[] ) => { return new Observable((observer) => { @@ -811,7 +814,7 @@ describe("BatchLink", () => { expect(forward!.length).toBe(1); return forward![0]!(operation[0]).pipe(map((d: any) => [d])); - }) as BatchHandler); + }) as BatchLink.BatchHandler); const link = ApolloLink.from([ new BatchLink({ diff --git a/src/link/batch/batchLink.ts b/src/link/batch/batchLink.ts index e7aedcbf938..ff782d7617d 100644 --- a/src/link/batch/batchLink.ts +++ b/src/link/batch/batchLink.ts @@ -3,12 +3,14 @@ import { EMPTY } from "rxjs"; import { ApolloLink } from "@apollo/client/link"; -import type { BatchHandler } from "./batching.js"; import { OperationBatcher } from "./batching.js"; -export type { BatchableRequest, BatchHandler } from "./batching.js"; -export { OperationBatcher } from "./batching.js"; export declare namespace BatchLink { + export type BatchHandler = ( + operations: ApolloLink.Operation[], + forward: ApolloLink.ForwardFunction[] + ) => Observable; + export interface Options { /** * The interval at which to batch, in milliseconds. @@ -34,7 +36,7 @@ export declare namespace BatchLink { /** * The handler that should execute a batch of operations. */ - batchHandler?: BatchHandler; + batchHandler?: BatchLink.BatchHandler; /** * creates the key for a batch diff --git a/src/link/batch/batching.ts b/src/link/batch/batching.ts index 09ef474bbc0..b45d9b32488 100644 --- a/src/link/batch/batching.ts +++ b/src/link/batch/batching.ts @@ -3,10 +3,7 @@ import { Observable } from "rxjs"; import type { ApolloLink } from "@apollo/client/link"; -export type BatchHandler = ( - operations: ApolloLink.Operation[], - forward: ApolloLink.ForwardFunction[] -) => Observable; +import type { BatchLink } from "./batchLink.js"; export interface BatchableRequest { operation: ApolloLink.Operation; @@ -43,7 +40,7 @@ export class OperationBatcher { private batchMax: number; //This function is called to the queries in the queue to the server. - private batchHandler: BatchHandler; + private batchHandler: BatchLink.BatchHandler; private batchKey: (operation: ApolloLink.Operation) => string; constructor({ @@ -56,7 +53,7 @@ export class OperationBatcher { batchDebounce?: boolean; batchInterval?: number; batchMax?: number; - batchHandler: BatchHandler; + batchHandler: BatchLink.BatchHandler; batchKey?: (operation: ApolloLink.Operation) => string; }) { this.batchDebounce = batchDebounce; diff --git a/src/link/batch/index.ts b/src/link/batch/index.ts index 10f9644eb6e..d92d75a2711 100644 --- a/src/link/batch/index.ts +++ b/src/link/batch/index.ts @@ -1,2 +1 @@ -export type { BatchableRequest, BatchHandler } from "./batchLink.js"; -export { BatchLink, OperationBatcher } from "./batchLink.js"; +export { BatchLink } from "./batchLink.js"; diff --git a/src/link/error/index.ts b/src/link/error/index.ts index e1c8062c3d0..72a6232a018 100644 --- a/src/link/error/index.ts +++ b/src/link/error/index.ts @@ -46,14 +46,11 @@ export declare namespace ErrorLink { } } -// For backwards compatibility. -export import ErrorHandler = ErrorLink.ErrorHandler; - /** * @deprecated * Use `ErrorLink` from `@apollo/client/link/error` instead. */ -export function onError(errorHandler: ErrorHandler) { +export function onError(errorHandler: ErrorLink.ErrorHandler) { return new ErrorLink(errorHandler); } @@ -63,7 +60,7 @@ export class ErrorLink extends ApolloLink { return new Observable((observer) => { let sub: Subscription | undefined; let retriedSub: Subscription | undefined; - let retriedResult: ReturnType; + let retriedResult: ReturnType; try { sub = forward(operation).subscribe({ diff --git a/src/link/persisted-queries/index.ts b/src/link/persisted-queries/index.ts index a260f4e0896..f2cb411078d 100644 --- a/src/link/persisted-queries/index.ts +++ b/src/link/persisted-queries/index.ts @@ -30,44 +30,51 @@ import { defaultCacheSizes } from "../../utilities/caching/sizes.js"; export const VERSION = 1; -type ErrorMeta = { - persistedQueryNotSupported: boolean; - persistedQueryNotFound: boolean; -}; +export declare namespace PersistedQueryLink { + namespace Base { + interface Options { + disable?: (options: PersistedQueryLink.DisableFunctionOptions) => boolean; + retry?: (options: PersistedQueryLink.RetryFunctionOptions) => boolean; + useGETForHashedQueries?: boolean; + } + } -type SHA256Function = (...args: any[]) => string | PromiseLike; -type GenerateHashFunction = ( - document: DocumentNode -) => string | PromiseLike; + export interface ErrorMeta { + persistedQueryNotSupported: boolean; + persistedQueryNotFound: boolean; + } -interface BaseOptions { - disable?: (options: PersistedQueryLink.DisableFunctionOptions) => boolean; - retry?: (options: PersistedQueryLink.RetryFunctionOptions) => boolean; - useGETForHashedQueries?: boolean; -} + export type GenerateHashFunction = ( + document: DocumentNode + ) => string | PromiseLike; -export declare namespace PersistedQueryLink { - interface CallbackOptions { - error: ErrorLike; - operation: ApolloLink.Operation; - meta: ErrorMeta; - result?: FormattedExecutionResult; - } + export type SHA256Function = ( + queryString: string + ) => string | PromiseLike; - export interface SHA256Options extends BaseOptions { - sha256: SHA256Function; + export interface SHA256Options extends Base.Options { + sha256: PersistedQueryLink.SHA256Function; generateHash?: never; } - export interface GenerateHashOptions extends BaseOptions { + export interface GenerateHashOptions extends Base.Options { sha256?: never; - generateHash: GenerateHashFunction; + generateHash: PersistedQueryLink.GenerateHashFunction; } - export type Options = SHA256Options | GenerateHashOptions; + export type Options = + | PersistedQueryLink.SHA256Options + | PersistedQueryLink.GenerateHashOptions; + + export interface RetryFunctionOptions { + error: ErrorLike; + operation: ApolloLink.Operation; + meta: PersistedQueryLink.ErrorMeta; + result?: FormattedExecutionResult; + } - export interface RetryFunctionOptions extends CallbackOptions {} - export interface DisableFunctionOptions extends CallbackOptions {} + export interface DisableFunctionOptions + extends PersistedQueryLink.RetryFunctionOptions {} } function processErrors( @@ -75,7 +82,7 @@ function processErrors( | GraphQLFormattedError[] | ReadonlyArray | undefined -): ErrorMeta { +): PersistedQueryLink.ErrorMeta { const byMessage: Record = {}, byCode: Record = {}; @@ -97,7 +104,7 @@ function processErrors( }; } -const defaultOptions: Required = { +const defaultOptions: Required = { disable: ({ meta }) => meta.persistedQueryNotSupported, retry: ({ meta }) => meta.persistedQueryNotSupported || meta.persistedQueryNotFound, diff --git a/src/link/remove-typename/index.ts b/src/link/remove-typename/index.ts index ac07017b39c..9b745ed77a1 100644 --- a/src/link/remove-typename/index.ts +++ b/src/link/remove-typename/index.ts @@ -1,4 +1,3 @@ -export type { RemoveTypenameFromVariablesOptions } from "./removeTypenameFromVariables.js"; export { KEEP, removeTypenameFromVariables, diff --git a/src/link/remove-typename/removeTypenameFromVariables.ts b/src/link/remove-typename/removeTypenameFromVariables.ts index 42645739a12..5204b238055 100644 --- a/src/link/remove-typename/removeTypenameFromVariables.ts +++ b/src/link/remove-typename/removeTypenameFromVariables.ts @@ -13,12 +13,16 @@ import { defaultCacheSizes } from "../../utilities/caching/sizes.js"; export const KEEP = "__KEEP"; -interface KeepTypenameConfig { - [key: string]: typeof KEEP | KeepTypenameConfig; -} +export declare namespace RemoveTypenameFromVariablesLink { + export interface KeepTypenameConfig { + [key: string]: + | typeof KEEP + | RemoveTypenameFromVariablesLink.KeepTypenameConfig; + } -export interface RemoveTypenameFromVariablesOptions { - except?: KeepTypenameConfig; + export interface Options { + except?: RemoveTypenameFromVariablesLink.KeepTypenameConfig; + } } /** @@ -26,13 +30,13 @@ export interface RemoveTypenameFromVariablesOptions { * Use `RemoveTypenameFromVariablesLink` from `@apollo/client/link/remove-typename` instead. */ export function removeTypenameFromVariables( - options?: RemoveTypenameFromVariablesOptions + options?: RemoveTypenameFromVariablesLink.Options ) { return new RemoveTypenameFromVariablesLink(options); } export class RemoveTypenameFromVariablesLink extends ApolloLink { - constructor(options: RemoveTypenameFromVariablesOptions = {}) { + constructor(options: RemoveTypenameFromVariablesLink.Options = {}) { super((operation, forward) => { const { except } = options; const { query, variables } = operation; @@ -66,7 +70,7 @@ export class RemoveTypenameFromVariablesLink extends ApolloLink { function maybeStripTypenameUsingConfig( query: DocumentNode, variables: OperationVariables, - config: KeepTypenameConfig + config: RemoveTypenameFromVariablesLink.KeepTypenameConfig ) { const variableDefinitions = getVariableDefinitions(query); @@ -91,7 +95,7 @@ type JSONValue = JSONPrimitive | JSONValue[] | { [key: string]: JSONValue }; function maybeStripTypename( value: JSONValue, - config: KeepTypenameConfig[string] + config: RemoveTypenameFromVariablesLink.KeepTypenameConfig[string] ): JSONValue { if (config === KEEP) { return value; diff --git a/src/link/retry/delayFunction.ts b/src/link/retry/delayFunction.ts index 62fb08395ff..3fe144e7951 100644 --- a/src/link/retry/delayFunction.ts +++ b/src/link/retry/delayFunction.ts @@ -1,49 +1,8 @@ -import type { ApolloLink } from "@apollo/client/link"; - -/** - * Advanced mode: a function that implements the strategy for calculating delays - * for particular responses. - */ -export interface DelayFunction { - (count: number, operation: ApolloLink.Operation, error: any): number; -} - -export interface DelayFunctionOptions { - /** - * The number of milliseconds to wait before attempting the first retry. - * - * Delays will increase exponentially for each attempt. E.g. if this is - * set to 100, subsequent retries will be delayed by 200, 400, 800, etc, - * until they reach maxDelay. - * - * Note that if jittering is enabled, this is the _average_ delay. - * - * Defaults to 300. - */ - initial?: number; - - /** - * The maximum number of milliseconds that the link should wait for any - * retry. - * - * Defaults to Infinity. - */ - max?: number; - - /** - * Whether delays between attempts should be randomized. - * - * This helps avoid thundering herd type situations by better distributing - * load during major outages. - * - * Defaults to true. - */ - jitter?: boolean; -} +import type { RetryLink } from "./retryLink.js"; export function buildDelayFunction( - delayOptions?: DelayFunctionOptions -): DelayFunction { + delayOptions?: RetryLink.DelayOptions +): RetryLink.DelayFunction { const { initial = 300, jitter = true, max = Infinity } = delayOptions || {}; // If we're jittering, baseDelay is half of the maximum delay for that // attempt (and is, on average, the delay we will encounter). diff --git a/src/link/retry/retryFunction.ts b/src/link/retry/retryFunction.ts index a2aebbda3ec..025817eb047 100644 --- a/src/link/retry/retryFunction.ts +++ b/src/link/retry/retryFunction.ts @@ -1,46 +1,10 @@ -import type { ApolloLink } from "@apollo/client/link"; - -/** - * Advanced mode: a function that determines both whether a particular - * response should be retried. - */ -export interface RetryFunction { - ( - count: number, - operation: ApolloLink.Operation, - error: any - ): boolean | Promise; -} - -export interface RetryFunctionOptions { - /** - * The max number of times to try a single operation before giving up. - * - * Note that this INCLUDES the initial request as part of the count. - * E.g. maxTries of 1 indicates no retrying should occur. - * - * Defaults to 5. Pass Infinity for infinite retries. - */ - max?: number; - - /** - * Predicate function that determines whether a particular error should - * trigger a retry. - * - * For example, you may want to not retry 4xx class HTTP errors. - * - * By default, all errors are retried. - */ - retryIf?: ( - error: any, - operation: ApolloLink.Operation - ) => boolean | Promise; -} +import type { RetryLink } from "./retryLink.js"; export function buildRetryFunction( - retryOptions?: RetryFunctionOptions -): RetryFunction { - const { retryIf, max = 5 } = retryOptions || ({} as RetryFunctionOptions); + retryOptions?: RetryLink.AttemptsOptions +): RetryLink.AttemptsFunction { + const { retryIf, max = 5 } = + retryOptions || ({} as RetryLink.AttemptsOptions); return function retryFunction(count, operation, error) { if (count >= max) return false; return retryIf ? retryIf(error, operation) : !!error; diff --git a/src/link/retry/retryLink.ts b/src/link/retry/retryLink.ts index 9000f2b899e..e7fd2abd317 100644 --- a/src/link/retry/retryLink.ts +++ b/src/link/retry/retryLink.ts @@ -8,22 +8,91 @@ import { } from "@apollo/client/errors"; import { ApolloLink } from "@apollo/client/link"; -import type { DelayFunction, DelayFunctionOptions } from "./delayFunction.js"; import { buildDelayFunction } from "./delayFunction.js"; -import type { RetryFunction, RetryFunctionOptions } from "./retryFunction.js"; import { buildRetryFunction } from "./retryFunction.js"; export declare namespace RetryLink { + export type DelayFunction = ( + count: number, + operation: ApolloLink.Operation, + error: any + ) => number; + + export interface DelayOptions { + /** + * The number of milliseconds to wait before attempting the first retry. + * + * Delays will increase exponentially for each attempt. E.g. if this is + * set to 100, subsequent retries will be delayed by 200, 400, 800, etc, + * until they reach maxDelay. + * + * Note that if jittering is enabled, this is the _average_ delay. + * + * @defaultValue `300` + */ + initial?: number; + + /** + * The maximum number of milliseconds that the link should wait for any + * retry. + * + * @defaultValue `Infinity` + */ + max?: number; + + /** + * Whether delays between attempts should be randomized. + * + * This helps avoid thundering herd type situations by better distributing + * load during major outages. + * + * @defaultValue `true` + */ + jitter?: boolean; + } + + export type AttemptsFunction = ( + count: number, + operation: ApolloLink.Operation, + error: any + ) => boolean | Promise; + + export interface AttemptsOptions { + /** + * The max number of times to try a single operation before giving up. Pass + * `Infinity` for infinite retries. + * + * Note that this INCLUDES the initial request as part of the count. + * E.g. maxTries of 1 indicates no retrying should occur. + * + * @defaultValue `5` + */ + max?: number; + + /** + * Predicate function that determines whether a particular error should + * trigger a retry. + * + * For example, you may want to not retry 4xx class HTTP errors. + * + * @defaultValue `() => true` + */ + retryIf?: ( + error: any, + operation: ApolloLink.Operation + ) => boolean | Promise; + } + export interface Options { /** * Configuration for the delay strategy to use, or a custom delay strategy. */ - delay?: DelayFunctionOptions | DelayFunction; + delay?: RetryLink.DelayOptions | RetryLink.DelayFunction; /** * Configuration for the retry strategy to use, or a custom retry strategy. */ - attempts?: RetryFunctionOptions | RetryFunction; + attempts?: RetryLink.AttemptsOptions | RetryLink.AttemptsFunction; } } @@ -39,8 +108,8 @@ class RetryableOperation { private observer: Observer, private operation: ApolloLink.Operation, private forward: ApolloLink.ForwardFunction, - private delayFor: DelayFunction, - private retryIf: RetryFunction + private delayFor: RetryLink.DelayFunction, + private retryIf: RetryLink.AttemptsFunction ) { this.try(); } @@ -105,8 +174,8 @@ class RetryableOperation { } export class RetryLink extends ApolloLink { - private delayFor: DelayFunction; - private retryIf: RetryFunction; + private delayFor: RetryLink.DelayFunction; + private retryIf: RetryLink.AttemptsFunction; constructor(options?: RetryLink.Options) { super(); diff --git a/src/link/schema/index.ts b/src/link/schema/index.ts index 17ed085017a..65a4df113ce 100644 --- a/src/link/schema/index.ts +++ b/src/link/schema/index.ts @@ -24,7 +24,7 @@ export declare namespace SchemaLink { /** * A context to provide to resolvers declared within the schema. */ - context?: ResolverContext | ResolverContextFunction; + context?: SchemaLink.ResolverContext | SchemaLink.ResolverContextFunction; /** * Validate incoming queries against the given schema, returning