diff --git a/.api-reports/api-report-cache.md b/.api-reports/api-report-cache.md index b31968f747e..5e2df27abe7 100644 --- a/.api-reports/api-report-cache.md +++ b/.api-reports/api-report-cache.md @@ -90,7 +90,7 @@ namespace Cache_2 { // (undocumented) interface BatchOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -882,7 +882,7 @@ export interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -891,7 +891,7 @@ export type StoreValue = number | string | string[] | Reference | Reference[] | class Stump extends Layer { constructor(root: EntityStore.Root); // (undocumented) - merge(): any; + merge(older: string | StoreObject, newer: string | StoreObject): void; // (undocumented) removeLayer(): this; } diff --git a/.api-reports/api-report-core.md b/.api-reports/api-report-core.md index 119bc538d4e..8028536b8dd 100644 --- a/.api-reports/api-report-core.md +++ b/.api-reports/api-report-core.md @@ -300,7 +300,7 @@ namespace Cache_2 { // (undocumented) interface BatchOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -435,7 +435,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -933,8 +933,6 @@ export class HttpLink extends ApolloLink { constructor(options?: HttpOptions); // (undocumented) options: HttpOptions; - // (undocumented) - requester: RequestHandler; } // @public (undocumented) @@ -1168,15 +1166,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1320,14 +1316,12 @@ interface MutationBaseOptions; +export type MutationFetchPolicy = Extract; // Warning: (ae-forgotten-export) The symbol "MutationBaseOptions" needs to be exported by the entry point index.d.ts // // @public (undocumented) export interface MutationOptions = ApolloCache> extends MutationBaseOptions { - // Warning: (ae-forgotten-export) The symbol "MutationFetchPolicy" needs to be exported by the entry point index.d.ts - // // (undocumented) fetchPolicy?: MutationFetchPolicy; // (undocumented) @@ -1559,7 +1553,7 @@ export type OptimisticStoreItem = { }; // @public (undocumented) -type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; +type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; // @public (undocumented) export function parseAndCheckHttpResponse(operations: Operation | Operation[]): (response: Response) => Promise; @@ -1641,7 +1635,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1663,7 +1657,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1673,7 +1667,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1925,7 +1919,7 @@ export interface RefetchQueriesResult extends Promise Observable | null; @@ -1950,7 +1944,7 @@ export interface Resolvers { // // @public (undocumented) export function rewriteURIForGET(chosenURI: string, body: Body_2): { - parseError: any; + parseError: unknown; newURI?: undefined; } | { newURI: string; @@ -2024,7 +2018,7 @@ export interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2033,7 +2027,7 @@ export type StoreValue = number | string | string[] | Reference | Reference[] | class Stump extends Layer { constructor(root: EntityStore.Root); // (undocumented) - merge(): any; + merge(older: string | StoreObject, newer: string | StoreObject): void; // (undocumented) removeLayer(): this; } @@ -2155,8 +2149,6 @@ export interface WatchQueryOptions, currentFetchPolicy: WatchQueryFetchPolicy, context: NextFetchPolicyContext) => WatchQueryFetchPolicy); - // Warning: (ae-forgotten-export) The symbol "RefetchWritePolicy" needs to be exported by the entry point index.d.ts - // // (undocumented) refetchWritePolicy?: RefetchWritePolicy; } @@ -2199,11 +2191,11 @@ interface WriteContext extends ReadMergeModifyContext { // src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts // src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts // src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:119:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:153:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:384:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:114:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:120:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:154:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:385:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts // src/link/http/selectHttpOptionsAndBody.ts:128:32 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-link_http.md b/.api-reports/api-report-link_http.md index d106d1f3e6b..36cd6e1d814 100644 --- a/.api-reports/api-report-link_http.md +++ b/.api-reports/api-report-link_http.md @@ -180,8 +180,6 @@ export class HttpLink extends ApolloLink { constructor(options?: HttpOptions); // (undocumented) options: HttpOptions; - // (undocumented) - requester: RequestHandler; } // @public (undocumented) @@ -279,7 +277,7 @@ type RequestHandler = (operation: Operation, forward: NextLink) => Observable, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -552,7 +552,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -1023,15 +1023,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1454,7 +1452,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1478,7 +1476,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1488,7 +1486,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1864,7 +1862,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2211,18 +2209,18 @@ interface WatchQueryOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -493,7 +493,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -823,15 +823,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1260,7 +1258,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1284,7 +1282,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1294,7 +1292,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1601,7 +1599,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1745,11 +1743,11 @@ interface WatchQueryOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -476,7 +476,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -809,15 +809,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1168,7 +1166,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1192,7 +1190,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1202,7 +1200,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1534,7 +1532,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1641,11 +1639,11 @@ interface WatchQueryOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -469,7 +469,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -820,15 +820,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1237,7 +1235,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1261,7 +1259,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1271,7 +1269,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1556,7 +1554,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1686,11 +1684,11 @@ export function withSubscription, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -523,7 +523,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -974,15 +974,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1385,7 +1383,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1409,7 +1407,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1419,7 +1417,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1760,7 +1758,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2105,18 +2103,18 @@ interface WatchQueryOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -446,7 +446,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -795,15 +795,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1154,7 +1152,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1178,7 +1176,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1188,7 +1186,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1520,7 +1518,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1627,11 +1625,11 @@ interface WatchQueryOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -434,7 +434,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -766,7 +766,7 @@ function isReference(obj: any): obj is Reference; type IsStrictlyAny = UnionToIntersection> extends never ? true : false; // @public (undocumented) -export const itAsync: ((message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number | undefined) => any) & { +export const itAsync: ((this: unknown, message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number | undefined) => void) & { only: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; skip: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; todo: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; @@ -777,15 +777,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -962,7 +960,7 @@ export class MockSubscriptionLink extends ApolloLink { // (undocumented) onUnsubscribe(listener: any): void; // (undocumented) - operation: Operation; + operation?: Operation; // (undocumented) request(operation: Operation): Observable; // (undocumented) @@ -1242,7 +1240,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1266,7 +1264,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1276,7 +1274,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1562,7 +1560,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1690,11 +1688,11 @@ export function withWarningSpy(it: (...args: TArgs // src/cache/core/types/common.ts:100:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts // src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts // src/core/LocalState.ts:46:5 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:119:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:153:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:384:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:114:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:120:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:154:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:385:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:158:3 - (ae-forgotten-export) The symbol "ApolloError" needs to be exported by the entry point index.d.ts // src/core/types.ts:160:3 - (ae-forgotten-export) The symbol "NetworkStatus" needs to be exported by the entry point index.d.ts // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index db8ba43820e..a8494f44a28 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -312,7 +312,7 @@ namespace Cache_2 { // (undocumented) interface BatchOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -433,7 +433,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -765,7 +765,7 @@ function isReference(obj: any): obj is Reference; type IsStrictlyAny = UnionToIntersection> extends never ? true : false; // @public (undocumented) -export const itAsync: ((message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number | undefined) => any) & { +export const itAsync: ((this: unknown, message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number | undefined) => void) & { only: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; skip: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; todo: (message: string, callback: (resolve: (result?: any) => void, reject: (reason?: any) => void) => any, timeout?: number) => void; @@ -776,15 +776,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -916,7 +914,7 @@ export class MockSubscriptionLink extends ApolloLink { // (undocumented) onUnsubscribe(listener: any): void; // (undocumented) - operation: Operation; + operation?: Operation; // (undocumented) request(operation: Operation): Observable; // (undocumented) @@ -1196,7 +1194,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1220,7 +1218,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1230,7 +1228,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -1518,7 +1516,7 @@ interface StoreObject { // Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts // // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1646,11 +1644,11 @@ export function withWarningSpy(it: (...args: TArgs // src/cache/core/types/common.ts:100:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts // src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts // src/core/LocalState.ts:46:5 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:119:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:153:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:384:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:114:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:120:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:154:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:385:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:158:3 - (ae-forgotten-export) The symbol "ApolloError" needs to be exported by the entry point index.d.ts // src/core/types.ts:160:3 - (ae-forgotten-export) The symbol "NetworkStatus" needs to be exported by the entry point index.d.ts // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-utilities.md b/.api-reports/api-report-utilities.md index db99ac83b43..67a29e74257 100644 --- a/.api-reports/api-report-utilities.md +++ b/.api-reports/api-report-utilities.md @@ -354,7 +354,7 @@ namespace Cache_2 { // (undocumented) interface BatchOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -519,7 +519,7 @@ export class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -1404,15 +1404,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1820,7 +1818,7 @@ interface Operation { type OperationVariables = Record; // @public (undocumented) -type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; +type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; // @public (undocumented) type Path = ReadonlyArray; @@ -1907,7 +1905,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -1931,7 +1929,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -1941,7 +1939,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -2315,7 +2313,7 @@ export interface StoreObject { } // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2330,7 +2328,7 @@ export function stripTypename(value: T): DeepOmit; class Stump extends Layer { constructor(root: EntityStore.Root); // (undocumented) - merge(): any; + merge(older: string | StoreObject, newer: string | StoreObject): void; // (undocumented) removeLayer(): this; } @@ -2526,11 +2524,11 @@ interface WriteContext extends ReadMergeModifyContext { // src/cache/inmemory/writeToStore.ts:65:7 - (ae-forgotten-export) The symbol "MergeTree" needs to be exported by the entry point index.d.ts // src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts // src/core/LocalState.ts:71:3 - (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:119:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:153:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:384:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:114:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:120:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:154:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:385:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:158:3 - (ae-forgotten-export) The symbol "ApolloError" needs to be exported by the entry point index.d.ts // src/core/types.ts:160:3 - (ae-forgotten-export) The symbol "NetworkStatus" needs to be exported by the entry point index.d.ts // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index 174182d1f2c..e02fd3d7b75 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -402,7 +402,7 @@ namespace Cache_2 { // (undocumented) interface BatchOptions, TUpdateResult = void> { // (undocumented) - onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff: Cache_2.DiffResult | undefined) => any; + onWatchUpdated?: (this: TCache, watch: Cache_2.WatchOptions, diff: Cache_2.DiffResult, lastDiff?: Cache_2.DiffResult | undefined) => any; // (undocumented) optimistic?: string | boolean; // (undocumented) @@ -549,7 +549,7 @@ class Concast extends Observable { // (undocumented) cancel: (reason: any) => void; // (undocumented) - readonly promise: Promise; + readonly promise: Promise; // (undocumented) removeObserver(observer: Observer): void; } @@ -1108,8 +1108,6 @@ export class HttpLink extends ApolloLink { constructor(options?: HttpOptions); // (undocumented) options: HttpOptions; - // (undocumented) - requester: RequestHandler; } // @public (undocumented) @@ -1423,15 +1421,13 @@ class LocalState { // Warning: (ae-forgotten-export) The symbol "LocalStateOptions" needs to be exported by the entry point index.d.ts constructor({ cache, client, resolvers, fragmentMatcher, }: LocalStateOptions); // (undocumented) - addExportedVariables(document: DocumentNode, variables?: OperationVariables, context?: {}): Promise<{ - [x: string]: any; - }>; + addExportedVariables(document: DocumentNode, variables?: TVars, context?: {}): Promise; // (undocumented) addResolvers(resolvers: Resolvers | Resolvers[]): void; // (undocumented) clientQuery(document: DocumentNode): DocumentNode | null; // (undocumented) - getFragmentMatcher(): FragmentMatcher; + getFragmentMatcher(): FragmentMatcher | undefined; // (undocumented) getResolvers(): Resolvers; // (undocumented) @@ -1581,7 +1577,7 @@ export interface MutationDataOptions; +export type MutationFetchPolicy = Extract; // @public (undocumented) export type MutationFunction = ApolloCache> = (options?: MutationFunctionOptions) => Promise>; @@ -1600,8 +1596,6 @@ export interface MutationHookOptions = ApolloCache> extends MutationBaseOptions { - // Warning: (ae-forgotten-export) The symbol "MutationFetchPolicy" needs to be exported by the entry point index.d.ts - // // (undocumented) fetchPolicy?: MutationFetchPolicy; // (undocumented) @@ -1888,7 +1882,7 @@ export type OptimisticStoreItem = { }; // @public (undocumented) -type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; +type OptionsUnion = WatchQueryOptions | QueryOptions | MutationOptions; // @public (undocumented) export function parseAndCheckHttpResponse(operations: Operation | Operation[]): (response: Response) => Promise; @@ -2011,7 +2005,7 @@ class QueryInfo { document: DocumentNode; variables: Record | undefined; networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this; // (undocumented) @@ -2033,7 +2027,7 @@ class QueryInfo { // (undocumented) notify(): void; // (undocumented) - readonly observableQuery: ObservableQuery | null; + readonly observableQuery: ObservableQuery | null; // (undocumented) readonly queryId: string; // (undocumented) @@ -2043,7 +2037,7 @@ class QueryInfo { // (undocumented) setDiff(diff: Cache_2.DiffResult | null): void; // (undocumented) - setObservableQuery(oq: ObservableQuery | null): void; + setObservableQuery(oq: ObservableQuery | null): void; // (undocumented) stop(): void; // (undocumented) @@ -2340,7 +2334,7 @@ export interface RefetchQueriesResult extends Promise = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? StoreVal extends Array ? Item extends Record ? ReadonlyArray | Reference> : never : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2477,7 +2471,7 @@ export type StoreValue = number | string | string[] | Reference | Reference[] | class Stump extends Layer { constructor(root: EntityStore.Root); // (undocumented) - merge(): any; + merge(older: string | StoreObject, newer: string | StoreObject): void; // (undocumented) removeLayer(): this; } @@ -2837,8 +2831,6 @@ export interface WatchQueryOptions, currentFetchPolicy: WatchQueryFetchPolicy, context: NextFetchPolicyContext) => WatchQueryFetchPolicy); - // Warning: (ae-forgotten-export) The symbol "RefetchWritePolicy" needs to be exported by the entry point index.d.ts - // // (undocumented) refetchWritePolicy?: RefetchWritePolicy; } @@ -2881,15 +2873,15 @@ interface WriteContext extends ReadMergeModifyContext { // src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts // src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts // src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts -// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:119:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:153:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:384:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts +// src/core/ObservableQuery.ts:114:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:120:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:154:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:385:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts // src/link/http/selectHttpOptionsAndBody.ts:128:32 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts -// src/react/hooks/useBackgroundQuery.ts:24:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts -// src/react/hooks/useBackgroundQuery.ts:25:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts +// src/react/hooks/useBackgroundQuery.ts:26:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts +// src/react/hooks/useBackgroundQuery.ts:27:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/.changeset/chatty-plants-cheer.md b/.changeset/chatty-plants-cheer.md new file mode 100644 index 00000000000..79cd7b9cd19 --- /dev/null +++ b/.changeset/chatty-plants-cheer.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Enable `strict` in tsconfig for the entire project. diff --git a/.changeset/good-experts-repair.md b/.changeset/good-experts-repair.md deleted file mode 100644 index 37aef92f934..00000000000 --- a/.changeset/good-experts-repair.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@apollo/client": patch ---- - -Add an explicit return type for the `useReadQuery` hook called `UseReadQueryResult`. Previously the return type of this hook was inferred from the return value. diff --git a/.changeset/ninety-suits-flash.md b/.changeset/ninety-suits-flash.md new file mode 100644 index 00000000000..bba930c377e --- /dev/null +++ b/.changeset/ninety-suits-flash.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Add missed reexports of MutationFetchPolicy and RefetchWritePolicy to @apollo/client/core diff --git a/.changeset/yellow-fans-move.md b/.changeset/yellow-fans-move.md new file mode 100644 index 00000000000..936ec8a859c --- /dev/null +++ b/.changeset/yellow-fans-move.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +`useMutation`: also reset internal state on reset diff --git a/.circleci/config.yml b/.circleci/config.yml index 63bccebe163..278ee3f4b1d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - secops: apollo/circleci-secops-orb@2.0.1 + secops: apollo/circleci-secops-orb@2.0.2 jobs: # Filesize: diff --git a/.size-limit.cjs b/.size-limit.cjs index a15bd6aa160..f4ad9acaf4b 100644 --- a/.size-limit.cjs +++ b/.size-limit.cjs @@ -1,7 +1,7 @@ const checks = [ { path: "dist/apollo-client.min.cjs", - limit: "38124", + limit: "38142", }, { path: "dist/main.cjs", @@ -10,7 +10,7 @@ const checks = [ { path: "dist/index.js", import: "{ ApolloClient, InMemoryCache, HttpLink }", - limit: "32162", + limit: "32167", }, ...[ "ApolloProvider", diff --git a/CHANGELOG.md b/CHANGELOG.md index 054cc0a4438..1a4a642f012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,14 @@ - [#6701](https://github.com/apollographql/apollo-client/pull/6701) [`8d2b4e107`](https://github.com/apollographql/apollo-client/commit/8d2b4e107d7c21563894ced3a65d631183b58fd9) Thanks [@prowe](https://github.com/prowe)! - Ability to dynamically match mocks Adds support for a new property `MockedResponse.variableMatcher`: a predicate function that accepts a `variables` param. If `true`, the `variables` will be passed into the `ResultFunction` to help dynamically build a response. +## 3.8.7 + +### Patch Changes + +- [#11297](https://github.com/apollographql/apollo-client/pull/11297) [`c8c76a522`](https://github.com/apollographql/apollo-client/commit/c8c76a522e593de0d06cff73fde2d9e88152bed6) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Add an explicit return type for the `useReadQuery` hook called `UseReadQueryResult`. Previously the return type of this hook was inferred from the return value. + +- [#11337](https://github.com/apollographql/apollo-client/pull/11337) [`bb1da8349`](https://github.com/apollographql/apollo-client/commit/bb1da8349e785c54fb4030f269602c900adf23a0) Thanks [@phryneas](https://github.com/phryneas)! - #11206 used the TypeScript syntax `infer X extends Y` that was introduced in TS 4.8. + This caused some problems for some users, so we are rolling back to a more backwars-compatible (albeit slightly less performant) type. ## 3.8.6 diff --git a/ROADMAP.md b/ROADMAP.md index 081d877de06..59a9e819500 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # 🔮 Apollo Client Roadmap -**Last updated: 2023-09-26** +**Last updated: 2023-11-07** For up to date release notes, refer to the project's [Changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md). @@ -15,11 +15,12 @@ For up to date release notes, refer to the project's [Changelog](https://github. ## [3.9.0](https://github.com/apollographql/apollo-client/milestone/32) -_Currently in planning phase_ +_Currently in development phase_ + +Tentative beta date: Dec 1, 2023 Features we plan to tackle: -- Introduce a suspenseful `useFragment` that will suspend when the data is not yet loaded - Ability to preload a query outside of a React component that can be used with `useReadQuery` to suspend while loading - Introduce a new `useInteractiveQuery`/`useLazyBackgroundQuery` hook (name TBD) - Improved testing utilities @@ -29,6 +30,13 @@ Features we plan to tackle: ## Future 3.x releases +## [3.10.0](https://github.com/apollographql/apollo-client/milestone/33) + +_Currently in planning phase_ + +- schema-driven testing utilities +- Introduce a suspenseful `useFragment` that will suspend when the data is not yet loaded + _Approximate Date: TBD_ The 3.8 release was a major milestone for the project's React support. Feedback from the community will have a big impact on where we go next, particularly as use cases for React Server Components and other React 18 features emerge. In addition to new functionality, there is a significant backlog of questions and fixes that we want to categorize and thoughtfully address in upcoming releases. diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index da9e1cfeeca..3e58414e730 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -2,7 +2,7 @@ title: Advanced topics on caching in Apollo Client --- -This article describes special cases and considerations when using the Apollo Client cache. +This article describes special cases and considerations when using the [Apollo Client cache](./overview). ## Bypassing the cache @@ -22,7 +22,11 @@ You can persist and rehydrate the `InMemoryCache` from a storage provider like ` To get started, pass your cache and a storage provider to `persistCache`. By default, the contents of your cache are immediately restored asynchronously, and they're persisted on every write to the cache with a short configurable debounce interval. -> **Note:** The `persistCache` method is async and returns a `Promise`. + + +The `persistCache` method is async and returns a `Promise`. + + ```js import AsyncStorage from '@react-native-async-storage/async-storage'; @@ -60,7 +64,7 @@ function Profile() { } ``` -> To reset the cache _without_ refetching active queries, use `client.clearStore()` instead of `client.resetStore()`. +To reset the cache _without_ refetching active queries, use `client.clearStore()` instead of `client.resetStore()`. ### Responding to cache resets @@ -97,7 +101,7 @@ function Foo (){ const client = useApolloClient(); useEffect(() => { - const unsubscribe = client.onResetStore(() => + const unsubscribe = client.onResetStore(() => new Promise(()=>setReset(reset + 1)) ); @@ -174,7 +178,11 @@ In these cases, you can provide a `refetchQueries` option to the `useMutation` h For details, see [Refetching queries](../data/mutations/#refetching-queries). -> Note that although `refetchQueries` can be faster to implement than an `update` function, it also requires additional network requests that are usually undesirable. For more information, see [this blog post](https://www.apollographql.com/blog/when-to-use-refetch-queries-in-apollo-client/). + + +Although `refetchQueries` can be faster to implement than an `update` function, it also requires additional network requests that are usually undesirable. For more information, see [this blog post](https://www.apollographql.com/blog/when-to-use-refetch-queries-in-apollo-client/). + + ## Cache redirects @@ -233,23 +241,61 @@ This `read` function uses the `toReference` helper utility to generate and retur Now whenever a query includes the `book` field, the `read` function above executes and returns a reference to a `Book` object. Apollo Client uses this reference to look up the object in its cache and return it if it's present. If it _isn't_ present, Apollo Client knows it needs to execute the query over the network. -> ⚠️ **Note:** To avoid a network request, _all_ of a query's requested fields must already be present in the cache. If the detail view's query fetches _any_ `Book` field that the list view's query _didn't_, Apollo Client considers the cache hit to be incomplete, and it executes the full query over the network. + + +To avoid a network request, _all_ of a query's requested fields must already be present in the cache. If the detail view's query fetches _any_ `Book` field that the list view's query _didn't_, Apollo Client considers the cache hit to be incomplete, and it executes the full query over the network. + + ## Pagination utilities +Pagination is a best practice in GraphQL [for several reasons](../pagination/overview). Apollo Client enables fetching and caching paginated results using the [Core pagination API](../pagination/core-api). The API includes a few important utilities, including the [`fetchMore`](../pagination/core-api/#the-fetchmore-function) function and the `@connection` directive. + ### Incremental loading: `fetchMore` -You can use the `fetchMore` function to update a query's cached result with data returned by a _followup_ query. Most often, `fetchMore` is used to handle infinite-scroll pagination and other situations where you're loading _more_ data when you already have _some_. +You can use the `fetchMore` function to update a query's cached result with data returned by a _follow-up_ query. Most often, `fetchMore` is used to handle infinite-scroll pagination and other situations where you're loading more data when you already have some. For details, see [The `fetchMore` function](../pagination/core-api/#the-fetchmore-function). ### The `@connection` directive -Fundamentally, paginated queries are the same as any other query with the exception that calls to `fetchMore` update the same cache key. Because these queries are cached by both the initial query and their parameters, a problem arises when later retrieving or updating paginated queries in the cache. We don't care about pagination arguments such as limits, offsets, or cursors outside of the need to `fetchMore`, nor do we want to provide them simply for accessing cached data. +The `@connection` directive solves the problem of multiple copies of the same field in the cache. This can happen with paginated queries because the `fetchMore` function sends follow-up queries to fetch additional pages of results using arguments like [`offset`](../pagination/offset-based/) and [`limit`](../pagination/offset-based/). These arguments inadvertently fragment data from different pagination requests across the cache. + +The `@connection` directive lets you unify paginated results by specifying a custom, stable cache key for a field. It also lets you _intentionally_ separate paginated results in the cache by fields that you specify. + + + +Starting in Apollo Client v3, setting the [`keyArgs` field policy](../pagination/key-args/#setting-keyargs) is the most straightforward way to resolve fragmented pagination results in the cache. For example, setting [`keyArgs` to `false`](../pagination/key-args/#supported-values-for-keyargs) indicates that no arguments should be included in cache keys, causing all pagination results to be cached together. Additionally, you only have to set your `keyArgs` configuration once, rather than using `@connection` in multiple queries. Refer to the [usage instructions](#connection-directive-usage) below to compare `@connection` and `keyArgs` usage. + +The `@connection` directive is useful when you want to store distinct data in the cache on a query-by-query, field-by-field basis. See the [advanced usage instructions](#advanced-connection-directive-usage) for more details. + + + +#### `@connection` directive usage + + + +For the standard `@connection` directive usage described in this section, it's best to configure a [`keyArgs` field policy](../pagination/key-args/#setting-keyargs). For example, you can use the following [`keyArgs`](../pagination/key-args/#setting-keyargs) configuration for the same effect as the `@connection` example below. + +```js +const cache = new InMemoryCache({ + typePolicies: { + Query: { + fields: { + feed: { + keyArgs: ["type"] + } + } + } + } +}) +``` + +With this centralized `keyArg`s configuration, you don't need to include the `@connection` directive in your queries because the `type` argument is adequate for keeping feeds of different types separate in the cache. For an example of storing distinct data on a query-by-query basis, see the [advanced usage instructions](#advanced-connection-directive-usage). -To solve this, you can use the `@connection` directive to specify a custom cache key for results. A connection allows us to set the cache key for a field and to filter which arguments actually alter the query. + -To use the `@connection` directive, add it to the segment of the query you want a custom store key for and provide the `key` parameter to specify the store key. In addition to the `key` parameter, you can also include the optional `filter` parameter, which takes an array of query argument names to include in the generated custom store key. +To use the `@connection` directive, add it to the field you want a custom cache key for. The directive requires a `key` parameter to specify the custom cache key. You can optionally include the `filter` parameter, which takes an array of query argument names to include in the generated custom cache key. ```js const query = gql` @@ -261,9 +307,9 @@ const query = gql` ` ``` -With the above query, even with multiple `fetchMore`s, the results of each feed update will always result in the `feed` key in the store being updated with the latest accumulated values. In this example, we also use the `@connection` directive's optional `filter` argument to include the `type` query argument in the store key, which results in multiple store values that accumulate queries from each type of feed. +With the above query, even when multiple `fetchMore`s queries are performed, each feed update always results in an update to the cache's `feed` key with the latest accumulated values. The example also uses the `@connection` directive's optional `filter` argument to include the `type` query argument in the cache key. This creates multiple cache values that accumulate queries from each type of feed. -Now that we have a stable store key, we can easily use `writeQuery` to perform a store update, in this case clearing out the feed. +With a stable cache key, you can use [`writeQuery`](./cache-interaction/#writequery) to perform a cache update that clears out the feed. ```js client.writeQuery({ @@ -283,4 +329,24 @@ client.writeQuery({ }); ``` -Note that because we are only using the `type` argument in the store key, we don't have to provide `offset` or `limit`. + + +Because this example uses the `type` argument in the cache key, it doesn't need to provide `offset` or `limit` arguments. + + + +#### Advanced `@connection` directive usage + +The `@connection` directive is useful when using the same field in multiple queries, with no distinguishing arguments (for example, `type`) that `keyArgs` can use, and you want to keep that field's data separate in the cache. + +For example, Apollo's [Spotify showcase](https://github.com/apollographql/spotify-showcase) uses `@connection` to independently cache lists of playlists. One list is in the left sidebar, where you navigate between playlists. The other appears when you right-click a song to add it to a playlist. + + +Separately cached playlists in Apollo's Spotify Showcase + +Without caching the playlists separately, loading the next page of data from one list affects the other, negatively impacting the UX. + +For code examples, see: +- [The type policy](https://github.com/apollographql/spotify-showcase/blob/185f7b8a155209e9a099490dbc5d1e3bfba4c32f/client/src/apollo/client.ts#L105-L108) +- [Playlist sidebar query](https://github.com/apollographql/spotify-showcase/blob/185f7b8a155209e9a099490dbc5d1e3bfba4c32f/client/src/components/LoggedInLayout.tsx#L75) +- [Add to playlist menu](https://github.com/apollographql/spotify-showcase/blob/185f7b8a155209e9a099490dbc5d1e3bfba4c32f/client/src/components/ContextMenuAction/AddToPlaylist.tsx#L17) diff --git a/docs/source/img/spotify-playlists.jpg b/docs/source/img/spotify-playlists.jpg new file mode 100644 index 00000000000..2c2584c38bd Binary files /dev/null and b/docs/source/img/spotify-playlists.jpg differ diff --git a/docs/source/integrations/react-native.md b/docs/source/integrations/react-native.md index eabd1ec6076..68dfdd23bf6 100644 --- a/docs/source/integrations/react-native.md +++ b/docs/source/integrations/react-native.md @@ -17,7 +17,7 @@ import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'; // Initialize Apollo Client const client = new ApolloClient({ - uri: 'localhost:4000/graphql', + uri: 'http://localhost:4000/graphql', cache: new InMemoryCache() }); diff --git a/package-lock.json b/package-lock.json index 8956ec4bd09..9cf8221c770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "@changesets/changelog-github": "0.4.8", "@changesets/cli": "2.26.2", "@graphql-tools/schema": "10.0.0", - "@microsoft/api-extractor": "7.38.0", + "@microsoft/api-extractor": "7.38.2", "@rollup/plugin-node-resolve": "11.2.1", "@size-limit/esbuild-why": "8.2.6", "@size-limit/preset-small-lib": "8.2.6", @@ -44,11 +44,11 @@ "@types/fetch-mock": "7.3.7", "@types/glob": "8.1.0", "@types/hoist-non-react-statics": "3.3.4", - "@types/jest": "29.5.6", + "@types/jest": "29.5.7", "@types/lodash": "4.14.200", - "@types/node": "20.8.9", - "@types/node-fetch": "2.6.7", - "@types/react": "18.2.33", + "@types/node": "20.8.10", + "@types/node-fetch": "2.6.8", + "@types/react": "18.2.35", "@types/react-dom": "18.2.14", "@types/relay-runtime": "14.1.14", "@types/use-sync-external-store": "0.0.5", @@ -2113,9 +2113,9 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.38.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.0.tgz", - "integrity": "sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg==", + "version": "7.38.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.2.tgz", + "integrity": "sha512-JOARuhTwOcOMIU0O2czscoJy3ddVzIRhSA9/7T1ALuZSNphgWsPk+Bv4E7AnBDmTV4pP4lBNLtCxEHjjpWaytQ==", "dev": true, "dependencies": { "@microsoft/api-extractor-model": "7.28.2", @@ -2123,7 +2123,7 @@ "@microsoft/tsdoc-config": "~0.16.1", "@rushstack/node-core-library": "3.61.0", "@rushstack/rig-package": "0.5.1", - "@rushstack/ts-command-line": "4.16.1", + "@rushstack/ts-command-line": "4.17.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -2342,9 +2342,9 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.1.tgz", - "integrity": "sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz", + "integrity": "sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==", "dev": true, "dependencies": { "@types/argparse": "1.0.38", @@ -2819,9 +2819,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.6", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.6.tgz", - "integrity": "sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w==", + "version": "29.5.7", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.7.tgz", + "integrity": "sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -2902,18 +2902,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", - "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", + "version": "20.8.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", + "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", "dev": true, "dependencies": { "@types/node": "*", @@ -2933,9 +2933,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.33", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.33.tgz", - "integrity": "sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==", + "version": "18.2.35", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.35.tgz", + "integrity": "sha512-LG3xpFZ++rTndV+/XFyX5vUP7NI9yxyk+MQvBDq+CVs8I9DLSc3Ymwb1Vmw5YDoeNeHN4PDZa3HylMKJYT9PNQ==", "dev": true, "dependencies": { "@types/prop-types": "*", diff --git a/package.json b/package.json index 11e0780bc3a..3a7d6f0196f 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "@changesets/changelog-github": "0.4.8", "@changesets/cli": "2.26.2", "@graphql-tools/schema": "10.0.0", - "@microsoft/api-extractor": "7.38.0", + "@microsoft/api-extractor": "7.38.2", "@rollup/plugin-node-resolve": "11.2.1", "@size-limit/esbuild-why": "8.2.6", "@size-limit/preset-small-lib": "8.2.6", @@ -122,11 +122,11 @@ "@types/fetch-mock": "7.3.7", "@types/glob": "8.1.0", "@types/hoist-non-react-statics": "3.3.4", - "@types/jest": "29.5.6", + "@types/jest": "29.5.7", "@types/lodash": "4.14.200", - "@types/node": "20.8.9", - "@types/node-fetch": "2.6.7", - "@types/react": "18.2.33", + "@types/node": "20.8.10", + "@types/node-fetch": "2.6.8", + "@types/react": "18.2.35", "@types/react-dom": "18.2.14", "@types/relay-runtime": "14.1.14", "@types/use-sync-external-store": "0.0.5", diff --git a/src/__tests__/ApolloClient.ts b/src/__tests__/ApolloClient.ts index 50c668f934c..993691abe0c 100644 --- a/src/__tests__/ApolloClient.ts +++ b/src/__tests__/ApolloClient.ts @@ -4,7 +4,6 @@ import { ApolloClient, ApolloError, DefaultOptions, - FetchPolicy, QueryOptions, makeReference, } from "../core"; @@ -2126,8 +2125,8 @@ describe("ApolloClient", () => { } `; - ["network-only", "cache-and-network"].forEach( - (fetchPolicy: FetchPolicy) => { + (["network-only", "cache-and-network"] as const).forEach( + (fetchPolicy) => { const observable = client.watchQuery({ query, fetchPolicy, @@ -2156,13 +2155,15 @@ describe("ApolloClient", () => { } `; - [ - "cache-first", - "cache-and-network", - "network-only", - "cache-only", - "no-cache", - ].forEach((fetchPolicy: FetchPolicy) => { + ( + [ + "cache-first", + "cache-and-network", + "network-only", + "cache-only", + "no-cache", + ] as const + ).forEach((fetchPolicy) => { const observable = client.watchQuery({ query, fetchPolicy, diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index fb1068dcb3c..c435220e116 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -1821,7 +1821,7 @@ describe("client", () => { link, cache: new InMemoryCache({ - dataIdFromObject: (obj: { id: any }) => obj.id, + dataIdFromObject: (obj: any) => obj.id, addTypename: false, }), }); @@ -1870,7 +1870,7 @@ describe("client", () => { callback(); throw new Error("not reached"); } catch (thrown) { - expect(thrown.message).toBe(cacheAndNetworkError); + expect((thrown as Error).message).toBe(cacheAndNetworkError); } } diff --git a/src/__tests__/graphqlSubscriptions.ts b/src/__tests__/graphqlSubscriptions.ts index 8b46eb01c26..2f4d66228d9 100644 --- a/src/__tests__/graphqlSubscriptions.ts +++ b/src/__tests__/graphqlSubscriptions.ts @@ -488,7 +488,7 @@ describe("GraphQL Subscriptions", () => { client.subscribe(options).subscribe({ next() { - expect(link.operation.getContext().someVar).toEqual( + expect(link.operation?.getContext().someVar).toEqual( options.context.someVar ); resolve(); diff --git a/src/__tests__/local-state/general.ts b/src/__tests__/local-state/general.ts index 30d31feea33..0d65993e821 100644 --- a/src/__tests__/local-state/general.ts +++ b/src/__tests__/local-state/general.ts @@ -1207,7 +1207,7 @@ describe("Combining client and server state/operations", () => { watchCount += 1; client.mutate({ mutation, - update(proxy, { data: { updateUser } }: { data: any }) { + update(proxy, { data: { updateUser } }) { proxy.writeQuery({ query: userQuery, data: { diff --git a/src/__tests__/local-state/resolvers.ts b/src/__tests__/local-state/resolvers.ts index c1052748841..b305a3ed7d8 100644 --- a/src/__tests__/local-state/resolvers.ts +++ b/src/__tests__/local-state/resolvers.ts @@ -11,7 +11,7 @@ import { WatchQueryOptions, } from "../../core"; -import { InMemoryCache } from "../../cache"; +import { InMemoryCache, isReference } from "../../cache"; import { Observable, Observer } from "../../utilities"; import { ApolloLink } from "../../link/core"; import { itAsync } from "../../testing"; @@ -747,10 +747,13 @@ describe("Writing cache data from resolvers", () => { }, }, }); - cache.modify({ + cache.modify<{ field: { field2: number } }>({ id: "Object:uniqueId", fields: { - field(value: { field2: number }) { + field(value) { + if (isReference(value)) { + fail("Should not be a reference"); + } expect(value.field2).toBe(1); return { ...value, field2: 2 }; }, diff --git a/src/__tests__/optimistic.ts b/src/__tests__/optimistic.ts index d8c20501821..4184a2f8d6d 100644 --- a/src/__tests__/optimistic.ts +++ b/src/__tests__/optimistic.ts @@ -235,7 +235,7 @@ describe("optimistic mutation results", () => { await promise; } catch (err) { expect(err).toBeInstanceOf(Error); - expect(err.message).toBe("forbidden (test error)"); + expect((err as Error).message).toBe("forbidden (test error)"); const dataInStore = (client.cache as InMemoryCache).extract(true); expect((dataInStore["TodoList5"] as any).todos.length).toBe(3); @@ -489,7 +489,7 @@ describe("optimistic mutation results", () => { await promise; } catch (err) { expect(err).toBeInstanceOf(Error); - expect(err.message).toBe("forbidden (test error)"); + expect((err as Error).message).toBe("forbidden (test error)"); const dataInStore = (client.cache as InMemoryCache).extract(true); expect((dataInStore["TodoList5"] as any).todos.length).toBe(3); @@ -2019,11 +2019,12 @@ describe("optimistic mutation results", () => { const wrapReject = ( fn: (...args: TArgs) => TResult ): typeof fn => { - return function () { + return function (this: unknown, ...args: TArgs) { try { - return fn.apply(this, arguments); + return fn.apply(this, args); } catch (e) { reject(e); + throw e; } }; }; diff --git a/src/__tests__/subscribeToMore.ts b/src/__tests__/subscribeToMore.ts index 2903dacdbbd..419b0b696d0 100644 --- a/src/__tests__/subscribeToMore.ts +++ b/src/__tests__/subscribeToMore.ts @@ -8,8 +8,10 @@ import { itAsync, mockSingleLink, mockObservableLink } from "../testing"; const isSub = (operation: Operation) => (operation.query as DocumentNode).definitions - .filter((x) => x.kind === "OperationDefinition") - .some((x: OperationDefinitionNode) => x.operation === "subscription"); + .filter( + (x): x is OperationDefinitionNode => x.kind === "OperationDefinition" + ) + .some((x) => x.operation === "subscription"); describe("subscribeToMore", () => { const query = gql` diff --git a/src/cache/core/types/Cache.ts b/src/cache/core/types/Cache.ts index 8628f272a19..58835e6aca5 100644 --- a/src/cache/core/types/Cache.ts +++ b/src/cache/core/types/Cache.ts @@ -93,7 +93,7 @@ export namespace Cache { this: TCache, watch: Cache.WatchOptions, diff: Cache.DiffResult, - lastDiff: Cache.DiffResult | undefined + lastDiff?: Cache.DiffResult | undefined ) => any; } diff --git a/src/cache/core/types/common.ts b/src/cache/core/types/common.ts index 19200d4845e..9dc18d9197f 100644 --- a/src/cache/core/types/common.ts +++ b/src/cache/core/types/common.ts @@ -106,9 +106,13 @@ export type Modifier = ( ) => T | DeleteModifier | InvalidateModifier; type StoreObjectValueMaybeReference = StoreVal extends Array< - infer Item extends Record + Record > - ? ReadonlyArray | Reference> + ? StoreVal extends Array + ? Item extends Record + ? ReadonlyArray | Reference> + : never + : never : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index a7289cd2c64..edaa63fb4d4 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -4035,6 +4035,7 @@ describe("ReactiveVar and makeVar", () => { let broadcastCount = 0; cache["broadcastWatches"] = function () { ++broadcastCount; + // @ts-expect-error return broadcast.apply(this, arguments); }; diff --git a/src/cache/inmemory/__tests__/diffAgainstStore.ts b/src/cache/inmemory/__tests__/diffAgainstStore.ts index 5beef906247..0a315c60270 100644 --- a/src/cache/inmemory/__tests__/diffAgainstStore.ts +++ b/src/cache/inmemory/__tests__/diffAgainstStore.ts @@ -493,8 +493,8 @@ describe("diffing queries against the store", () => { }; const cache = new InMemoryCache({ - dataIdFromObject({ id }: { id: string }) { - return id; + dataIdFromObject(obj: any) { + return obj.id; }, }); @@ -841,7 +841,7 @@ describe("diffing queries against the store", () => { const writer = new StoreWriter( new InMemoryCache({ - dataIdFromObject: ({ id }: { id: string }) => id, + dataIdFromObject: (obj: any) => obj.id, }) ); @@ -1067,7 +1067,7 @@ describe("diffing queries against the store", () => { }); throw new Error("should have thrown"); } catch (e) { - expect(e.message).toEqual( + expect((e as Error).message).toEqual( "Missing selection set for object of type Message returned for query field messageList" ); } diff --git a/src/cache/inmemory/__tests__/readFromStore.ts b/src/cache/inmemory/__tests__/readFromStore.ts index 99472adc335..328336ec3ed 100644 --- a/src/cache/inmemory/__tests__/readFromStore.ts +++ b/src/cache/inmemory/__tests__/readFromStore.ts @@ -1904,7 +1904,7 @@ describe("reading from the store", () => { ); expect(value.__ref).toBe('Deity:{"name":"Zeus"}'); // Interim ruler Apollo takes over for real. - return toReference(apolloRulerResult.ruler); + return toReference(apolloRulerResult.ruler)!; }, }, }); diff --git a/src/cache/inmemory/__tests__/roundtrip.ts b/src/cache/inmemory/__tests__/roundtrip.ts index 6f04fabe5d7..5c6824cdc6e 100644 --- a/src/cache/inmemory/__tests__/roundtrip.ts +++ b/src/cache/inmemory/__tests__/roundtrip.ts @@ -61,7 +61,7 @@ function storeRoundtrip(query: DocumentNode, result: any, variables = {}) { (immutableResult as any).illegal = "this should not work"; throw new Error("unreached"); } catch (e) { - expect(e.message).not.toMatch(/unreached/); + expect((e as Error).message).not.toMatch(/unreached/); expect(e).toBeInstanceOf(TypeError); } assertDeeplyFrozen(immutableResult); diff --git a/src/cache/inmemory/__tests__/writeToStore.ts b/src/cache/inmemory/__tests__/writeToStore.ts index f1911b0a3c4..e00b21d9bba 100644 --- a/src/cache/inmemory/__tests__/writeToStore.ts +++ b/src/cache/inmemory/__tests__/writeToStore.ts @@ -25,9 +25,14 @@ import { defaultNormalizedCacheFactory, writeQueryToStore } from "./helpers"; import { InMemoryCache } from "../inMemoryCache"; import { TypedDocumentNode } from "../../../core"; import { extractFragmentContext } from "../helpers"; +import { KeyFieldsFunction } from "../policies"; +import { invariant } from "../../../utilities/globals"; import { spyOnConsole } from "../../../testing/internal"; -const getIdField = ({ id }: { id: string }) => id; +const getIdField: KeyFieldsFunction = ({ id }) => { + invariant(typeof id === "string", "id is not a string"); + return id; +}; describe("writing to the store", () => { const cache = new InMemoryCache({ @@ -1293,19 +1298,17 @@ describe("writing to the store", () => { } testData.forEach((data) => { - data.mutation.definitions.forEach( - (definition: OperationDefinitionNode) => { - if (isOperationDefinition(definition)) { - definition.selectionSet.selections.forEach((selection) => { - if (isField(selection)) { - expect( - storeKeyNameFromField(selection, data.variables) - ).toEqual(data.expected); - } - }); - } + data.mutation.definitions.forEach((definition) => { + if (isOperationDefinition(definition)) { + definition.selectionSet.selections.forEach((selection) => { + if (isField(selection)) { + expect(storeKeyNameFromField(selection, data.variables)).toEqual( + data.expected + ); + } + }); } - ); + }); }); }); @@ -1357,7 +1360,7 @@ describe("writing to the store", () => { return value.kind === "OperationDefinition"; } - mutation.definitions.map((def: OperationDefinitionNode) => { + mutation.definitions.map((def) => { if (isOperationDefinition(def)) { const writer = new StoreWriter( new InMemoryCache({ diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index ddb03b274da..a31f96db63a 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -593,7 +593,7 @@ class CacheGroup { // Used by the EntityStore#makeCacheKey method to compute cache keys // specific to this CacheGroup. - public keyMaker: Trie; + public keyMaker!: Trie; constructor( public readonly caching: boolean, @@ -800,7 +800,11 @@ class Layer extends EntityStore { public getStorage(): StorageType { let p: EntityStore = this.parent; while ((p as Layer).parent) p = (p as Layer).parent; - return p.getStorage.apply(p, arguments); + return p.getStorage.apply( + p, + // @ts-expect-error + arguments + ); } } @@ -823,20 +827,20 @@ class Stump extends Layer { return this; } - public merge() { + public merge(older: string | StoreObject, newer: string | StoreObject) { // We never want to write any data into the Stump, so we forward any merge // calls to the Root instead. Another option here would be to throw an // exception, but the toReference(object, true) function can sometimes // trigger Stump writes (which used to be Root writes, before the Stump // concept was introduced). - return this.parent.merge.apply(this.parent, arguments); + return this.parent.merge(older, newer); } } function storeObjectReconciler( existingObject: StoreObject, incomingObject: StoreObject, - property: string + property: string | number ): StoreValue { const existingValue = existingObject[property]; const incomingValue = incomingObject[property]; diff --git a/src/cache/inmemory/fixPolyfills.native.ts b/src/cache/inmemory/fixPolyfills.native.ts index d2302429c74..4b75824841a 100644 --- a/src/cache/inmemory/fixPolyfills.native.ts +++ b/src/cache/inmemory/fixPolyfills.native.ts @@ -33,10 +33,10 @@ try { // https://github.com/apollographql/react-apollo/issues/2442#issuecomment-426489517 testMap.set(frozen, frozen).delete(frozen); } catch { - const wrap = (method: (obj: T) => T): typeof method => { + const wrap = (obj: T) => T>(method: M): M => { return ( method && - ((obj) => { + (((obj) => { try { // If .set succeeds, also call .delete to avoid leaking memory. testMap.set(obj, obj).delete(obj); @@ -45,7 +45,7 @@ try { // by this return-from-finally statement: return method.call(Object, obj); } - }) + }) as M) ); }; Object.freeze = wrap(Object.freeze); diff --git a/src/cache/inmemory/fragmentRegistry.ts b/src/cache/inmemory/fragmentRegistry.ts index e868122d1d2..0832e6a7934 100644 --- a/src/cache/inmemory/fragmentRegistry.ts +++ b/src/cache/inmemory/fragmentRegistry.ts @@ -6,6 +6,7 @@ import type { } from "graphql"; import { visit } from "graphql"; +import type { OptimisticWrapperFunction } from "optimism"; import { wrap } from "optimism"; import type { FragmentMap } from "../../utilities/index.js"; @@ -29,24 +30,22 @@ export function createFragmentRegistry( return new FragmentRegistry(...fragments); } -const { forEach: arrayLikeForEach } = Array.prototype; - class FragmentRegistry implements FragmentRegistryAPI { private registry: FragmentMap = Object.create(null); - // Call static method FragmentRegistry.from(...) instead of invoking the + // Call `createFragmentRegistry` instead of invoking the // FragmentRegistry constructor directly. This reserves the constructor for // future configuration of the FragmentRegistry. constructor(...fragments: DocumentNode[]) { this.resetCaches(); if (fragments.length) { - this.register.apply(this, fragments); + this.register(...fragments); } } - public register(): this { + public register(...fragments: DocumentNode[]): this { const definitions = new Map(); - arrayLikeForEach.call(arguments, (doc: DocumentNode) => { + fragments.forEach((doc: DocumentNode) => { getFragmentDefinitions(doc).forEach((node) => { definitions.set(node.name.value, node); }); @@ -66,27 +65,15 @@ class FragmentRegistry implements FragmentRegistryAPI { private invalidate(name: string) {} public resetCaches() { - this.invalidate = (this.lookup = this.cacheUnaryMethod("lookup")).dirty; // This dirty function is bound to the wrapped lookup method. - this.transform = this.cacheUnaryMethod("transform"); - this.findFragmentSpreads = this.cacheUnaryMethod("findFragmentSpreads"); + this.invalidate = (this.lookup = this.cacheUnaryMethod(this.lookup)).dirty; // This dirty function is bound to the wrapped lookup method. + this.transform = this.cacheUnaryMethod(this.transform); + this.findFragmentSpreads = this.cacheUnaryMethod(this.findFragmentSpreads); } - private cacheUnaryMethod< - TName extends keyof Pick< - FragmentRegistry, - "lookup" | "transform" | "findFragmentSpreads" - >, - >(name: TName) { - const registry = this; - const originalMethod = FragmentRegistry.prototype[name]; - return wrap( - function () { - return originalMethod.apply(registry, arguments); - }, - { - makeCacheKey: (arg) => arg, - } - ); + private cacheUnaryMethod any>(originalMethod: F) { + return wrap, ReturnType>(originalMethod.bind(this), { + makeCacheKey: (arg) => arg, + }) as OptimisticWrapperFunction, ReturnType> & F; } public lookup(fragmentName: string): FragmentDefinitionNode | null { diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 1297b6eeb19..1cce80d023b 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -34,18 +34,18 @@ type BroadcastOptions = Pick< >; export class InMemoryCache extends ApolloCache { - private data: EntityStore; - private optimisticData: EntityStore; + private data!: EntityStore; + private optimisticData!: EntityStore; protected config: InMemoryCacheConfig; private watches = new Set(); private addTypename: boolean; - private storeReader: StoreReader; - private storeWriter: StoreWriter; + private storeReader!: StoreReader; + private storeWriter!: StoreWriter; private addTypenameTransform = new DocumentTransform(addTypenameToDocument); - private maybeBroadcastWatch: OptimisticWrapperFunction< + private maybeBroadcastWatch!: OptimisticWrapperFunction< [Cache.WatchOptions, BroadcastOptions?], any, [Cache.WatchOptions] diff --git a/src/cache/inmemory/readFromStore.ts b/src/cache/inmemory/readFromStore.ts index 0643233b947..4ddbea78b43 100644 --- a/src/cache/inmemory/readFromStore.ts +++ b/src/cache/inmemory/readFromStore.ts @@ -536,7 +536,7 @@ function firstMissing(tree: MissingTree): string | undefined { return value; }); } catch (result) { - return result; + return result as string; } } diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts index c667286c36a..e0486d941d8 100644 --- a/src/core/ApolloClient.ts +++ b/src/core/ApolloClient.ts @@ -87,7 +87,7 @@ export class ApolloClient implements DataProxy { public readonly typeDefs: ApolloClientOptions["typeDefs"]; private queryManager: QueryManager; - private devToolsHookCb: Function; + private devToolsHookCb?: Function; private resetStoreCallbacks: Array<() => Promise> = []; private clearStoreCallbacks: Array<() => Promise> = []; private localState: LocalState; @@ -595,7 +595,9 @@ export class ApolloClient implements DataProxy { >( options: RefetchQueriesOptions ): RefetchQueriesResult { - const map = this.queryManager.refetchQueries(options); + const map = this.queryManager.refetchQueries( + options as RefetchQueriesOptions, TResult> + ); const queries: ObservableQuery[] = []; const results: InternalRefetchQueriesResult[] = []; diff --git a/src/core/LocalState.ts b/src/core/LocalState.ts index 6f0aaf61f08..4b68b787c2a 100644 --- a/src/core/LocalState.ts +++ b/src/core/LocalState.ts @@ -75,9 +75,9 @@ export type LocalStateOptions = { export class LocalState { private cache: ApolloCache; - private client: ApolloClient; + private client?: ApolloClient; private resolvers?: Resolvers; - private fragmentMatcher: FragmentMatcher; + private fragmentMatcher?: FragmentMatcher; private selectionsToResolveCache = new WeakMap< ExecutableDefinitionNode, Set @@ -162,7 +162,7 @@ export class LocalState { this.fragmentMatcher = fragmentMatcher; } - public getFragmentMatcher(): FragmentMatcher { + public getFragmentMatcher(): FragmentMatcher | undefined { return this.fragmentMatcher; } @@ -197,11 +197,11 @@ export class LocalState { // To support `@client @export(as: "someVar")` syntax, we'll first resolve // @client @export fields locally, then pass the resolved values back to be // used alongside the original operation variables. - public async addExportedVariables( + public async addExportedVariables( document: DocumentNode, - variables: OperationVariables = {}, + variables: TVars = {} as TVars, context = {} - ) { + ): /* returns at least the variables that were passed in */ Promise { if (document) { return this.resolveDocument( document, diff --git a/src/core/ObservableQuery.ts b/src/core/ObservableQuery.ts index 57f0867276f..bda85a543a7 100644 --- a/src/core/ObservableQuery.ts +++ b/src/core/ObservableQuery.ts @@ -35,6 +35,7 @@ import type { QueryInfo } from "./QueryInfo.js"; import type { MissingFieldError } from "../cache/index.js"; import type { MissingTree } from "../cache/core/types/common.js"; import { equalByQuery } from "./equalByQuery.js"; +import type { TODO } from "../utilities/types/TODO.js"; const { assign, hasOwnProperty } = Object; @@ -924,8 +925,9 @@ Did you mean to call refetch(variables) instead of refetch({ variables })?`, public reobserve( newOptions?: Partial>, newNetworkStatus?: NetworkStatus - ) { - return this.reobserveAsConcast(newOptions, newNetworkStatus).promise; + ): Promise> { + return this.reobserveAsConcast(newOptions, newNetworkStatus) + .promise as TODO; } public resubscribeAfterError( @@ -1048,14 +1050,18 @@ export function reobserveCacheFirst( fetchPolicy: "cache-first", // Use a temporary nextFetchPolicy function that replaces itself with the // previous nextFetchPolicy value and returns the original fetchPolicy. - nextFetchPolicy(this: WatchQueryOptions) { + nextFetchPolicy( + this: WatchQueryOptions, + currentFetchPolicy: WatchQueryFetchPolicy, + context: NextFetchPolicyContext + ) { // Replace this nextFetchPolicy function in the options object with the // original this.options.nextFetchPolicy value. this.nextFetchPolicy = nextFetchPolicy; // If the original nextFetchPolicy value was a function, give it a // chance to decide what happens here. - if (typeof nextFetchPolicy === "function") { - return nextFetchPolicy.apply(this, arguments); + if (typeof this.nextFetchPolicy === "function") { + return this.nextFetchPolicy(currentFetchPolicy, context); } // Otherwise go back to the original this.options.fetchPolicy. return fetchPolicy!; diff --git a/src/core/QueryInfo.ts b/src/core/QueryInfo.ts index d7c1d02e0a7..54a922704b7 100644 --- a/src/core/QueryInfo.ts +++ b/src/core/QueryInfo.ts @@ -49,6 +49,7 @@ function wrapDestructiveCacheMethod( // that matters in any conceivable practical scenario. (destructiveMethodCounts.get(cache)! + 1) % 1e15 ); + // @ts-expect-error this is just too generic to be typed correctly return original.apply(this, arguments); }; } @@ -111,7 +112,7 @@ export class QueryInfo { // NetworkStatus.loading, but also possibly fetchMore, poll, refetch, // or setVariables. networkStatus?: NetworkStatus; - observableQuery?: ObservableQuery; + observableQuery?: ObservableQuery; lastRequestId?: number; }): this { let networkStatus = query.networkStatus || NetworkStatus.loading; @@ -212,10 +213,10 @@ export class QueryInfo { } } - public readonly observableQuery: ObservableQuery | null = null; + public readonly observableQuery: ObservableQuery | null = null; private oqListener?: QueryListener; - setObservableQuery(oq: ObservableQuery | null) { + setObservableQuery(oq: ObservableQuery | null) { if (oq === this.observableQuery) return; if (this.oqListener) { diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index f24e7f2947a..e19cfdd71a3 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -76,6 +76,7 @@ import { import type { ApolloErrorOptions } from "../errors/index.js"; import { PROTOCOL_ERRORS_SYMBOL } from "../errors/index.js"; import { print } from "../utilities/index.js"; +import type { TODO } from "../utilities/types/TODO.js"; const { hasOwnProperty } = Object.prototype; @@ -485,7 +486,7 @@ export class QueryManager { const results: any[] = []; this.refetchQueries({ - updateCache: (cache: TCache) => { + updateCache: (cache) => { if (!skipCache) { cacheWrites.forEach((write) => cache.write(write)); } @@ -532,7 +533,7 @@ export class QueryManager { // either a SingleExecutionResult or the final ExecutionPatchResult, // call the update function. if (isFinalResult) { - update(cache, result, { + update(cache as TCache, result, { context: mutation.context, variables: mutation.variables, }); @@ -623,7 +624,7 @@ export class QueryManager { networkStatus?: NetworkStatus ): Promise> { return this.fetchConcastWithInfo(queryId, options, networkStatus).concast - .promise; + .promise as TODO; } public getQueryStore() { diff --git a/src/core/__tests__/ObservableQuery.ts b/src/core/__tests__/ObservableQuery.ts index 3104be8ea96..add7b8a61ee 100644 --- a/src/core/__tests__/ObservableQuery.ts +++ b/src/core/__tests__/ObservableQuery.ts @@ -46,7 +46,8 @@ export const mockFetchQuery = (queryManager: QueryManager) => { >( original: T ) => - jest.fn, Parameters>(function () { + jest.fn, Parameters>(function (): ReturnType { + // @ts-expect-error return original.apply(queryManager, arguments); }); @@ -2740,7 +2741,7 @@ describe("ObservableQuery", () => { throw new Error("not reached"); } catch (error) { expect(error).toBeInstanceOf(TypeError); - expect(error.message).toMatch( + expect((error as Error).message).toMatch( /Cannot assign to read only property 'value'/ ); } diff --git a/src/core/__tests__/QueryManager/index.ts b/src/core/__tests__/QueryManager/index.ts index b9ec7fef183..be28a6b575e 100644 --- a/src/core/__tests__/QueryManager/index.ts +++ b/src/core/__tests__/QueryManager/index.ts @@ -1602,7 +1602,7 @@ describe("QueryManager", () => { }); }); - const getIdField = ({ id }: { id: string }) => id; + const getIdField = (obj: any) => obj.id; itAsync( "runs a mutation with object parameters and puts the result in the store", diff --git a/src/core/index.ts b/src/core/index.ts index 72340d689d7..5757cdb2071 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -14,6 +14,8 @@ export type { SubscriptionOptions, FetchPolicy, WatchQueryFetchPolicy, + MutationFetchPolicy, + RefetchWritePolicy, ErrorPolicy, FetchMoreQueryOptions, SubscribeToMoreOptions, diff --git a/src/link/batch-http/__tests__/batchHttpLink.ts b/src/link/batch-http/__tests__/batchHttpLink.ts index 525636addb6..544f44c304f 100644 --- a/src/link/batch-http/__tests__/batchHttpLink.ts +++ b/src/link/batch-http/__tests__/batchHttpLink.ts @@ -35,10 +35,11 @@ function makeCallback( ) { return function () { try { + // @ts-expect-error callback.apply(this, arguments); resolve(); } catch (error) { - reject(error); + reject(error as Error); } } as typeof callback; } @@ -472,7 +473,7 @@ describe("SharedHttpTest", () => { after(); } catch (e) { - reject(e); + reject(e as Error); } }, }); diff --git a/src/link/batch/__tests__/batchLink.ts b/src/link/batch/__tests__/batchLink.ts index 1a564fd2796..e5930924c27 100644 --- a/src/link/batch/__tests__/batchLink.ts +++ b/src/link/batch/__tests__/batchLink.ts @@ -64,6 +64,7 @@ function terminatingCheck( ) { return function () { try { + // @ts-expect-error callback.apply(this, arguments); resolve(); } catch (error) { diff --git a/src/link/error/index.ts b/src/link/error/index.ts index ec5d6dffba9..7122ff792e8 100644 --- a/src/link/error/index.ts +++ b/src/link/error/index.ts @@ -84,7 +84,7 @@ export function onError(errorHandler: ErrorHandler): ApolloLink { }, }); } catch (e) { - errorHandler({ networkError: e, operation, forward }); + errorHandler({ networkError: e as Error, operation, forward }); observer.error(e); } diff --git a/src/link/http/HttpLink.ts b/src/link/http/HttpLink.ts index 06479e050f2..c59c04566cf 100644 --- a/src/link/http/HttpLink.ts +++ b/src/link/http/HttpLink.ts @@ -1,10 +1,8 @@ -import type { RequestHandler } from "../core/index.js"; import { ApolloLink } from "../core/index.js"; import type { HttpOptions } from "./selectHttpOptionsAndBody.js"; import { createHttpLink } from "./createHttpLink.js"; export class HttpLink extends ApolloLink { - public requester: RequestHandler; constructor(public options: HttpOptions = {}) { super(createHttpLink(options).request); } diff --git a/src/link/http/__tests__/HttpLink.ts b/src/link/http/__tests__/HttpLink.ts index 4523c4d0fcb..b2ce5308cfd 100644 --- a/src/link/http/__tests__/HttpLink.ts +++ b/src/link/http/__tests__/HttpLink.ts @@ -92,10 +92,11 @@ function makeCallback( ) { return function () { try { + // @ts-expect-error callback.apply(this, arguments); resolve(); } catch (error) { - reject(error); + reject(error as Error); } } as typeof callback; } @@ -1202,7 +1203,7 @@ describe("HttpLink", () => { reject("warning wasn't called"); } catch (e) { makeCallback(resolve, reject, () => - expect(e.message).toMatch(/has not been found globally/) + expect((e as Error).message).toMatch(/has not been found globally/) )(); } }); @@ -1214,7 +1215,7 @@ describe("HttpLink", () => { reject("warning wasn't called"); } catch (e) { makeCallback(resolve, reject, () => - expect(e.message).toMatch(/has not been found globally/) + expect((e as Error).message).toMatch(/has not been found globally/) )(); } }); diff --git a/src/link/http/__tests__/responseIterator.ts b/src/link/http/__tests__/responseIterator.ts index 74ffa328c60..3800a257a8d 100644 --- a/src/link/http/__tests__/responseIterator.ts +++ b/src/link/http/__tests__/responseIterator.ts @@ -17,10 +17,11 @@ function makeCallback( ) { return function () { try { + // @ts-expect-error callback.apply(this, arguments); resolve(); } catch (error) { - reject(error); + reject(error as Error); } } as typeof callback; } diff --git a/src/link/http/iterators/reader.ts b/src/link/http/iterators/reader.ts index 3a81e37cf2a..d9feac48d07 100644 --- a/src/link/http/iterators/reader.ts +++ b/src/link/http/iterators/reader.ts @@ -6,7 +6,7 @@ import { canUseAsyncIteratorSymbol } from "../../../utilities/index.js"; interface ReaderIterator { - next(): Promise>; + next(): Promise>; [Symbol.asyncIterator]?(): AsyncIterator; } @@ -15,12 +15,20 @@ export default function readerIterator( ): AsyncIterableIterator { const iterator: ReaderIterator = { next() { - return reader.read(); + return reader.read() as Promise< + | ReadableStreamReadValueResult + // DoneResult has `value` optional, which doesn't comply with an + // `IteratorResult`, so we assert it to `T | undefined` instead + | Required> + >; }, }; if (canUseAsyncIteratorSymbol) { - iterator[Symbol.asyncIterator] = function (): AsyncIterator { + iterator[Symbol.asyncIterator] = function (): AsyncIterator< + T, + T | undefined + > { return this; }; } diff --git a/src/link/http/serializeFetchParameter.ts b/src/link/http/serializeFetchParameter.ts index 4ad2b3db2cd..5a08fe67269 100644 --- a/src/link/http/serializeFetchParameter.ts +++ b/src/link/http/serializeFetchParameter.ts @@ -9,7 +9,7 @@ export const serializeFetchParameter = (p: any, label: string) => { let serialized; try { serialized = JSON.stringify(p); - } catch (e) { + } catch (e: any) { const parseError = newInvariantError( `Network request failed. %s is not serializable: %s`, label, diff --git a/src/link/persisted-queries/__tests__/persisted-queries.test.ts b/src/link/persisted-queries/__tests__/persisted-queries.test.ts index 37fc4c9c476..ea8b56e660a 100644 --- a/src/link/persisted-queries/__tests__/persisted-queries.test.ts +++ b/src/link/persisted-queries/__tests__/persisted-queries.test.ts @@ -219,7 +219,7 @@ describe("happy path", () => { reject("should have thrown an error"); } catch (error) { expect( - error.message.indexOf( + (error as Error).message.indexOf( 'Missing/invalid "sha256" or "generateHash" function' ) ).toBe(0); @@ -238,7 +238,7 @@ describe("happy path", () => { reject("should have thrown an error"); } catch (error) { expect( - error.message.indexOf( + (error as Error).message.indexOf( 'Missing/invalid "sha256" or "generateHash" function' ) ).toBe(0); @@ -569,6 +569,7 @@ describe("failure path", () => { status, }); } + // @ts-expect-error return global.fetch.apply(null, args); }; const link = createPersistedQuery({ sha256 }).concat( @@ -623,6 +624,7 @@ describe("failure path", () => { status, }); } + // @ts-expect-error return global.fetch.apply(null, args); }; const link = createPersistedQuery({ sha256 }).concat( @@ -662,6 +664,7 @@ describe("failure path", () => { status, }); } + // @ts-expect-error return global.fetch.apply(null, args); }; diff --git a/src/react/cache/QueryReference.ts b/src/react/cache/QueryReference.ts index f1ad5732bac..5b2fc14c643 100644 --- a/src/react/cache/QueryReference.ts +++ b/src/react/cache/QueryReference.ts @@ -73,7 +73,7 @@ export class InternalQueryReference { private subscription: ObservableSubscription; private listeners = new Set>(); - private autoDisposeTimeoutId: NodeJS.Timeout; + private autoDisposeTimeoutId?: NodeJS.Timeout; private status: "idle" | "loading" = "loading"; private resolve: ((result: ApolloQueryResult) => void) | undefined; diff --git a/src/react/cache/SuspenseCache.ts b/src/react/cache/SuspenseCache.ts index e5f8036ecea..af883c0a52a 100644 --- a/src/react/cache/SuspenseCache.ts +++ b/src/react/cache/SuspenseCache.ts @@ -32,7 +32,9 @@ export class SuspenseCache { cacheKey: CacheKey, createObservable: () => ObservableQuery ) { - const ref = this.queryRefs.lookupArray(cacheKey); + const ref = this.queryRefs.lookupArray(cacheKey) as { + current?: InternalQueryReference; + }; if (!ref.current) { ref.current = new InternalQueryReference(createObservable(), { @@ -44,6 +46,6 @@ export class SuspenseCache { }); } - return ref.current as InternalQueryReference; + return ref.current; } } diff --git a/src/react/hoc/__tests__/fragments.test.tsx b/src/react/hoc/__tests__/fragments.test.tsx index 1597a4b7092..741e5e2f8f7 100644 --- a/src/react/hoc/__tests__/fragments.test.tsx +++ b/src/react/hoc/__tests__/fragments.test.tsx @@ -55,7 +55,7 @@ describe("fragments", () => { ); throw new Error(); } catch (e) { - expect(e.name).toMatch(/Invariant Violation/); + expect((e as Error).name).toMatch(/Invariant Violation/); } }); diff --git a/src/react/hoc/__tests__/queries/errors.test.tsx b/src/react/hoc/__tests__/queries/errors.test.tsx index 449e3c46c67..dfe92de05ce 100644 --- a/src/react/hoc/__tests__/queries/errors.test.tsx +++ b/src/react/hoc/__tests__/queries/errors.test.tsx @@ -105,7 +105,7 @@ describe("[queries] errors", () => { try { unmount(); - } catch (e) { + } catch (e: any) { throw new Error(e); } }); @@ -220,6 +220,7 @@ describe("[queries] errors", () => { "setVar", 1 )( + // @ts-expect-error graphql(query)( class extends React.Component> { componentDidUpdate() { diff --git a/src/react/hoc/__tests__/queries/updateQuery.test.tsx b/src/react/hoc/__tests__/queries/updateQuery.test.tsx index 0d3056b862e..b11de81c326 100644 --- a/src/react/hoc/__tests__/queries/updateQuery.test.tsx +++ b/src/react/hoc/__tests__/queries/updateQuery.test.tsx @@ -143,7 +143,7 @@ describe("[queries] updateQuery", () => { ).toBeTruthy(); try { this.props.data!.updateQuery((p) => p); - } catch (e) { + } catch (e: any) { // TODO: branch never hit in test expect(e.toString()).toMatch( /ObservableQuery with this id doesn't exist:/ diff --git a/src/react/hoc/__tests__/ssr/getDataFromTree.test.tsx b/src/react/hoc/__tests__/ssr/getDataFromTree.test.tsx index b4a0ab6fc6c..13172453f78 100644 --- a/src/react/hoc/__tests__/ssr/getDataFromTree.test.tsx +++ b/src/react/hoc/__tests__/ssr/getDataFromTree.test.tsx @@ -945,6 +945,7 @@ describe("SSR", () => { ); + // @ts-expect-error const WrappedElement = withQuery(withMutation(Element)); const app = ( diff --git a/src/react/hoc/mutation-hoc.tsx b/src/react/hoc/mutation-hoc.tsx index 9e0917d0b6e..2b51ff97927 100644 --- a/src/react/hoc/mutation-hoc.tsx +++ b/src/react/hoc/mutation-hoc.tsx @@ -87,6 +87,7 @@ export function withMutation< return ( + {/* @ts-expect-error */} {( mutate: MutationFunction, { data, ...r }: MutationResult diff --git a/src/react/hooks/__tests__/useMutation.test.tsx b/src/react/hooks/__tests__/useMutation.test.tsx index 3ba88663d85..45619b63b68 100644 --- a/src/react/hooks/__tests__/useMutation.test.tsx +++ b/src/react/hooks/__tests__/useMutation.test.tsx @@ -23,13 +23,14 @@ import { MockSubscriptionLink, mockSingleLink, subscribeAndCount, + MockedResponse, } from "../../../testing"; import { ApolloProvider } from "../../context"; import { useQuery } from "../useQuery"; import { useMutation } from "../useMutation"; import { BatchHttpLink } from "../../../link/batch-http"; import { FetchResult } from "../../../link/core"; -import { spyOnConsole } from "../../../testing/internal"; +import { profileHook, spyOnConsole } from "../../../testing/internal"; describe("useMutation Hook", () => { interface Todo { @@ -719,6 +720,90 @@ describe("useMutation Hook", () => { { interval: 1 } ); }); + + it("resetting while a mutation is running: ensure that the result doesn't end up in the hook", async () => { + const CREATE_TODO_DATA = { + createTodo: { + id: 1, + priority: "Low", + description: "Get milk!", + __typename: "Todo", + }, + }; + + const mocks: MockedResponse[] = [ + { + request: { + query: CREATE_TODO_MUTATION, + variables: { + priority: "Low", + description: "Get milk.", + }, + }, + result: { + data: CREATE_TODO_DATA, + }, + delay: 20, + }, + ]; + + const ProfiledHook = profileHook(() => + useMutation< + { createTodo: Todo }, + { priority: string; description: string } + >(CREATE_TODO_MUTATION) + ); + + render(, { + wrapper: ({ children }) => ( + {children} + ), + }); + + let createTodo: Awaited>[0]; + let reset: Awaited< + ReturnType + >[1]["reset"]; + + { + const [mutate, result] = await ProfiledHook.takeSnapshot(); + createTodo = mutate; + reset = result.reset; + //initial value + expect(result.data).toBe(undefined); + expect(result.loading).toBe(false); + expect(result.called).toBe(false); + } + + let fetchResult: any; + act(() => { + fetchResult = createTodo({ + variables: { priority: "Low", description: "Get milk." }, + }); + }); + + { + const [, result] = await ProfiledHook.takeSnapshot(); + // started loading + expect(result.data).toBe(undefined); + expect(result.loading).toBe(true); + expect(result.called).toBe(true); + } + + act(() => reset()); + + { + const [, result] = await ProfiledHook.takeSnapshot(); + // reset to initial value + expect(result.data).toBe(undefined); + expect(result.loading).toBe(false); + expect(result.called).toBe(false); + } + + expect(await fetchResult).toEqual({ data: CREATE_TODO_DATA }); + + await expect(ProfiledHook).not.toRerender(); + }); }); describe("Callbacks", () => { diff --git a/src/react/hooks/useBackgroundQuery.ts b/src/react/hooks/useBackgroundQuery.ts index 99a41f5e5eb..20b2e978aa7 100644 --- a/src/react/hooks/useBackgroundQuery.ts +++ b/src/react/hooks/useBackgroundQuery.ts @@ -1,8 +1,10 @@ import * as React from "rehackt"; import type { DocumentNode, + FetchMoreQueryOptions, OperationVariables, TypedDocumentNode, + WatchQueryOptions, } from "../../core/index.js"; import { useApolloClient } from "./useApolloClient.js"; import { wrapQueryRef } from "../cache/QueryReference.js"; @@ -197,7 +199,7 @@ export function useBackgroundQuery< ]; const queryRef = suspenseCache.getQueryRef(cacheKey, () => - client.watchQuery(watchQueryOptions) + client.watchQuery(watchQueryOptions as WatchQueryOptions) ); const [promiseCache, setPromiseCache] = React.useState( @@ -213,7 +215,7 @@ export function useBackgroundQuery< const fetchMore: FetchMoreFunction = React.useCallback( (options) => { - const promise = queryRef.fetchMore(options); + const promise = queryRef.fetchMore(options as FetchMoreQueryOptions); setPromiseCache((promiseCache) => new Map(promiseCache).set(queryRef.key, queryRef.promise) diff --git a/src/react/hooks/useLazyQuery.ts b/src/react/hooks/useLazyQuery.ts index 81f988ded50..5c84211f5d4 100644 --- a/src/react/hooks/useLazyQuery.ts +++ b/src/react/hooks/useLazyQuery.ts @@ -75,6 +75,7 @@ export function useLazyQuery< // Only the first time populating execOptionsRef.current matters here. internalState.forceUpdateState(); } + // @ts-expect-error this is just too generic to type return method.apply(this, arguments); }; } diff --git a/src/react/hooks/useMutation.ts b/src/react/hooks/useMutation.ts index fe76e167218..3123d456fa0 100644 --- a/src/react/hooks/useMutation.ts +++ b/src/react/hooks/useMutation.ts @@ -12,6 +12,7 @@ import type { import type { ApolloCache, DefaultContext, + MutationOptions, OperationVariables, } from "../../core/index.js"; import { mergeOptions } from "../../utilities/index.js"; @@ -87,10 +88,10 @@ export function useMutation< } const mutationId = ++ref.current.mutationId; - const clientOptions = mergeOptions(baseOptions, executeOptions as any); + const clientOptions = mergeOptions(baseOptions, executeOptions); return client - .mutate(clientOptions) + .mutate(clientOptions as MutationOptions) .then((response) => { const { data, errors } = response; const error = @@ -102,7 +103,10 @@ export function useMutation< executeOptions.onError || ref.current.options?.onError; if (error && onError) { - onError(error, clientOptions); + onError( + error, + clientOptions as MutationOptions + ); } if ( @@ -126,7 +130,10 @@ export function useMutation< executeOptions.onCompleted || ref.current.options?.onCompleted; if (!error) { - onCompleted?.(response.data!, clientOptions); + onCompleted?.( + response.data!, + clientOptions as MutationOptions + ); } return response; @@ -150,7 +157,10 @@ export function useMutation< executeOptions.onError || ref.current.options?.onError; if (onError) { - onError(error, clientOptions); + onError( + error, + clientOptions as MutationOptions + ); // TODO(brian): why are we returning this here??? return { data: void 0, errors: error }; @@ -164,7 +174,9 @@ export function useMutation< const reset = React.useCallback(() => { if (ref.current.isMounted) { - setResult({ called: false, loading: false, client }); + const result = { called: false, loading: false, client }; + Object.assign(ref.current, { mutationId: 0, result }); + setResult(result); } }, []); diff --git a/src/react/hooks/useQuery.ts b/src/react/hooks/useQuery.ts index 7ff9cb085ff..965080216f2 100644 --- a/src/react/hooks/useQuery.ts +++ b/src/react/hooks/useQuery.ts @@ -271,8 +271,8 @@ class InternalState { // useQuery method, so we can safely use these members in other/later methods // without worrying they might be uninitialized. private renderPromises: ApolloContextValue["renderPromises"]; - private queryHookOptions: QueryHookOptions; - private watchQueryOptions: WatchQueryOptions; + private queryHookOptions!: QueryHookOptions; + private watchQueryOptions!: WatchQueryOptions; private useOptions(options: QueryHookOptions) { const watchQueryOptions = this.createWatchQueryOptions( @@ -461,8 +461,8 @@ class InternalState { private onCompleted(data: TData) {} private onError(error: ApolloError) {} - private observable: ObservableQuery; - private obsQueryFields: Omit< + private observable!: ObservableQuery; + private obsQueryFields!: Omit< ObservableQueryFields, "variables" >; diff --git a/src/react/hooks/useSuspenseQuery.ts b/src/react/hooks/useSuspenseQuery.ts index b92bfe2eea9..ed203d4cfee 100644 --- a/src/react/hooks/useSuspenseQuery.ts +++ b/src/react/hooks/useSuspenseQuery.ts @@ -178,7 +178,11 @@ export function useSuspenseQuery< ): UseSuspenseQueryResult { const client = useApolloClient(options.client); const suspenseCache = getSuspenseCache(client); - const watchQueryOptions = useWatchQueryOptions({ client, query, options }); + const watchQueryOptions = useWatchQueryOptions({ + client, + query, + options, + }); const { fetchPolicy, variables } = watchQueryOptions; const { queryKey = [] } = options; @@ -236,8 +240,8 @@ export function useSuspenseQuery< const result = fetchPolicy === "standby" ? skipResult : __use(promise); - const fetchMore: FetchMoreFunction = React.useCallback( - (options) => { + const fetchMore = React.useCallback( + ((options) => { const promise = queryRef.fetchMore(options); setPromiseCache((previousPromiseCache) => @@ -245,7 +249,10 @@ export function useSuspenseQuery< ); return promise; - }, + }) satisfies FetchMoreFunction< + unknown, + OperationVariables + > as FetchMoreFunction, [queryRef] ); @@ -262,13 +269,17 @@ export function useSuspenseQuery< [queryRef] ); - const subscribeToMore: SubscribeToMoreFunction = - React.useCallback( - (options) => queryRef.observable.subscribeToMore(options), - [queryRef] - ); + const subscribeToMore: SubscribeToMoreFunction< + TData | undefined, + TVariables + > = React.useCallback( + (options) => queryRef.observable.subscribeToMore(options), + [queryRef] + ); - return React.useMemo(() => { + return React.useMemo< + UseSuspenseQueryResult + >(() => { return { client, data: result.data, diff --git a/src/testing/core/itAsync.ts b/src/testing/core/itAsync.ts index 80fffe8f181..fc664cbac07 100644 --- a/src/testing/core/itAsync.ts +++ b/src/testing/core/itAsync.ts @@ -9,7 +9,7 @@ function wrap(key?: "only" | "skip" | "todo") { ) => (key ? it[key] : it)( message, - function () { + function (this: unknown) { return new Promise((resolve, reject) => callback.call(this, resolve, reject) ); @@ -21,7 +21,7 @@ function wrap(key?: "only" | "skip" | "todo") { const wrappedIt = wrap(); export const itAsync = Object.assign( - function (...args: Parameters) { + function (this: unknown, ...args: Parameters) { return wrappedIt.apply(this, args); }, { diff --git a/src/testing/core/mocking/mockLink.ts b/src/testing/core/mocking/mockLink.ts index 8b07e91065e..7c48201eb73 100644 --- a/src/testing/core/mocking/mockLink.ts +++ b/src/testing/core/mocking/mockLink.ts @@ -51,7 +51,7 @@ function requestToKey(request: GraphQLRequest, addTypename: Boolean): string { } export class MockLink extends ApolloLink { - public operation: Operation; + public operation!: Operation; public addTypename: Boolean = true; public showWarnings: boolean = true; private mockedResponsesByKey: { [key: string]: MockedResponse[] } = {}; diff --git a/src/testing/core/mocking/mockSubscriptionLink.ts b/src/testing/core/mocking/mockSubscriptionLink.ts index 93e48d5ddb4..b91c86e8b68 100644 --- a/src/testing/core/mocking/mockSubscriptionLink.ts +++ b/src/testing/core/mocking/mockSubscriptionLink.ts @@ -15,7 +15,7 @@ export interface MockedSubscriptionResult { export class MockSubscriptionLink extends ApolloLink { public unsubscribers: any[] = []; public setups: any[] = []; - public operation: Operation; + public operation?: Operation; private observers: any[] = []; diff --git a/src/testing/core/observableToPromise.ts b/src/testing/core/observableToPromise.ts index 4d8415d4838..004a013593c 100644 --- a/src/testing/core/observableToPromise.ts +++ b/src/testing/core/observableToPromise.ts @@ -11,7 +11,7 @@ import type { ObservableSubscription } from "../../utilities/index.js"; * @param errorCallbacks an expected set of errors */ export type Options = { - observable: ObservableQuery; + observable: ObservableQuery; shouldResolve?: boolean; wait?: number; errorCallbacks?: ((error: Error) => any)[]; diff --git a/src/testing/core/withConsoleSpy.ts b/src/testing/core/withConsoleSpy.ts index c5c425e6e33..01626d7f5f9 100644 --- a/src/testing/core/withConsoleSpy.ts +++ b/src/testing/core/withConsoleSpy.ts @@ -2,8 +2,7 @@ function wrapTestFunction( fn: (...args: any[]) => any, consoleMethodName: "log" | "warn" | "error" ) { - return function () { - const args = arguments; + return function (this: any, ...args: any[]) { const spy = jest.spyOn(console, consoleMethodName); spy.mockImplementation(() => {}); return new Promise((resolve) => { diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 12527844566..f4abb64af0e 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -203,7 +203,7 @@ export function profile< return render; }, async takeRender(options: NextRenderOptions = {}) { - let error: { message?: string } | undefined = undefined; + let error: unknown = undefined; try { return await Profiled.peekRender({ [_stackTrace]: captureStackTrace(Profiled.takeRender), diff --git a/src/testing/matchers/ProfiledComponent.ts b/src/testing/matchers/ProfiledComponent.ts index c733d50e241..469cfe00995 100644 --- a/src/testing/matchers/ProfiledComponent.ts +++ b/src/testing/matchers/ProfiledComponent.ts @@ -6,10 +6,10 @@ import type { ProfiledHook, } from "../internal/index.js"; export const toRerender: MatcherFunction<[options?: NextRenderOptions]> = - async function ( - _profiled: ProfiledComponent | ProfiledHook, - options?: NextRenderOptions - ) { + async function (actual, options) { + const _profiled = actual as + | ProfiledComponent + | ProfiledHook; const profiled = "ProfiledComponent" in _profiled ? _profiled.ProfiledComponent @@ -42,11 +42,10 @@ const failed = {}; export const toRenderExactlyTimes: MatcherFunction< [times: number, options?: NextRenderOptions] -> = async function ( - _profiled: ProfiledComponent | ProfiledHook, - times: number, - optionsPerRender?: NextRenderOptions -) { +> = async function (actual, times, optionsPerRender) { + const _profiled = actual as + | ProfiledComponent + | ProfiledHook; const profiled = "ProfiledComponent" in _profiled ? _profiled.ProfiledComponent : _profiled; const options = { timeout: 100, ...optionsPerRender }; diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 00000000000..321f038a735 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,14 @@ +// `tsconfig.json` for the editor only +// this config includes additional files (e.g. tests) that +// we don't want to see hooked up to the main build +// it can also add a few more types for that purpose +{ + "compilerOptions": { + "noEmit": true, + "lib": ["es2015", "esnext.asynciterable", "dom"], + "types": ["jest", "node", "./testing/matchers/index.d.ts"] + }, + "extends": "../tsconfig.json", + "include": ["./**/*.ts", "./**/*.tsx"], + "exclude": [] +} diff --git a/src/utilities/common/__tests__/mergeDeep.ts b/src/utilities/common/__tests__/mergeDeep.ts index fbf4ec16eb1..fcdc680e720 100644 --- a/src/utilities/common/__tests__/mergeDeep.ts +++ b/src/utilities/common/__tests__/mergeDeep.ts @@ -146,7 +146,7 @@ describe("mergeDeep", function () { }); it("supports custom reconciler functions", function () { - const merger = new DeepMerger((target, source, key) => { + const merger = new DeepMerger(function (target, source, key) { const targetValue = target[key]; const sourceValue = source[key]; if (Array.isArray(sourceValue)) { diff --git a/src/utilities/common/filterInPlace.ts b/src/utilities/common/filterInPlace.ts deleted file mode 100644 index cafeed316f2..00000000000 --- a/src/utilities/common/filterInPlace.ts +++ /dev/null @@ -1,14 +0,0 @@ -export function filterInPlace( - array: T[], - test: (elem: T) => boolean, - context?: any -): T[] { - let target = 0; - array.forEach(function (elem, i) { - if (test.call(this, elem, i, array)) { - array[target++] = elem; - } - }, context); - array.length = target; - return array; -} diff --git a/src/utilities/common/mergeDeep.ts b/src/utilities/common/mergeDeep.ts index a2171f9f023..451a7a56a20 100644 --- a/src/utilities/common/mergeDeep.ts +++ b/src/utilities/common/mergeDeep.ts @@ -72,7 +72,7 @@ const defaultReconciler: ReconcilerFunction = function ( export class DeepMerger { constructor( - private reconciler: ReconcilerFunction = defaultReconciler + private reconciler: ReconcilerFunction = defaultReconciler as any as ReconcilerFunction ) {} public merge(target: any, source: any, ...context: TContextArgs): any { diff --git a/src/utilities/common/mergeOptions.ts b/src/utilities/common/mergeOptions.ts index 9c945f904e4..fe4eb954bbf 100644 --- a/src/utilities/common/mergeOptions.ts +++ b/src/utilities/common/mergeOptions.ts @@ -10,7 +10,7 @@ import { compact } from "./compact.js"; type OptionsUnion = | WatchQueryOptions | QueryOptions - | MutationOptions; + | MutationOptions; export function mergeOptions< TDefaultOptions extends Partial>, diff --git a/src/utilities/graphql/transform.ts b/src/utilities/graphql/transform.ts index 7ff844ad150..1693ee73fee 100644 --- a/src/utilities/graphql/transform.ts +++ b/src/utilities/graphql/transform.ts @@ -12,7 +12,7 @@ import type { FragmentSpreadNode, VariableDefinitionNode, ASTNode, - ASTVisitor, + ASTVisitFn, InlineFragmentNode, } from "graphql"; import { visit, Kind } from "graphql"; @@ -29,6 +29,12 @@ import type { FragmentMap } from "./fragments.js"; import { createFragmentMap } from "./fragments.js"; import { isArray, isNonEmptyArray } from "../common/arrays.js"; +// https://github.com/graphql/graphql-js/blob/8d7c8fccf5a9846a50785de04abda58a7eb13fc0/src/language/visitor.ts#L20-L23 +interface EnterLeaveVisitor { + readonly enter?: ASTVisitFn; + readonly leave?: ASTVisitFn; +} + export type RemoveNodeConfig = { name?: string; test?: (node: N) => boolean; @@ -208,8 +214,10 @@ export function removeDirectivesFromDocument( // original doc immediately without any modifications. let firstVisitMadeChanges = false; - const fieldOrInlineFragmentVisitor: ASTVisitor = { - enter(node: FieldNode | InlineFragmentNode) { + const fieldOrInlineFragmentVisitor: EnterLeaveVisitor< + FieldNode | InlineFragmentNode + > = { + enter(node) { if (shouldRemoveField(node.directives)) { firstVisitMadeChanges = true; return null; @@ -385,8 +393,10 @@ export function removeDirectivesFromDocument( ) ); - const enterVisitor: ASTVisitor = { - enter(node: FragmentSpreadNode | FragmentDefinitionNode) { + const enterVisitor: EnterLeaveVisitor< + FragmentSpreadNode | FragmentDefinitionNode + > = { + enter(node) { if (fragmentWillBeRemoved(node.name.value)) { return null; } diff --git a/src/utilities/observables/Concast.ts b/src/utilities/observables/Concast.ts index e6df7e19882..c2fbb6fb180 100644 --- a/src/utilities/observables/Concast.ts +++ b/src/utilities/observables/Concast.ts @@ -147,9 +147,9 @@ export class Concast extends Observable { // Any Concast object can be trivially converted to a Promise, without // having to create a new wrapper Observable. This promise provides an // easy way to observe the final state of the Concast. - private resolve: (result?: T | PromiseLike) => void; - private reject: (reason: any) => void; - public readonly promise = new Promise((resolve, reject) => { + private resolve!: (result?: T | PromiseLike) => void; + private reject!: (reason: any) => void; + public readonly promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); diff --git a/src/utilities/observables/Observable.ts b/src/utilities/observables/Observable.ts index 04fd25cac30..5ee33965f30 100644 --- a/src/utilities/observables/Observable.ts +++ b/src/utilities/observables/Observable.ts @@ -17,6 +17,7 @@ export type { Observer, ObservableSubscription, Subscriber }; const { prototype } = Observable; const fakeObsSymbol = "@@observable" as keyof typeof prototype; if (!prototype[fakeObsSymbol]) { + // @ts-expect-error prototype[fakeObsSymbol] = function () { return this; }; diff --git a/src/utilities/observables/__tests__/Observable.ts b/src/utilities/observables/__tests__/Observable.ts index 47223bc0643..1729e0ae1f3 100644 --- a/src/utilities/observables/__tests__/Observable.ts +++ b/src/utilities/observables/__tests__/Observable.ts @@ -39,8 +39,13 @@ describe("Observable", () => { return constructor as any; } + type ObservableWithSub = Observable & { sub?: Subscriber }; + it("simulating super(sub) with Observable.call(this, sub)", () => { - function SubclassWithSuperCall(sub: Subscriber) { + function SubclassWithSuperCall( + this: ObservableWithSub, + sub: Subscriber + ) { const self = Observable.call(this, sub) || this; self.sub = sub; return self; @@ -49,7 +54,10 @@ describe("Observable", () => { }); it("simulating super(sub) with Observable.apply(this, arguments)", () => { - function SubclassWithSuperApplyArgs(_sub: Subscriber) { + function SubclassWithSuperApplyArgs( + this: ObservableWithSub, + _sub: Subscriber + ) { const self = Observable.apply(this, arguments) || this; self.sub = _sub; return self; @@ -58,7 +66,10 @@ describe("Observable", () => { }); it("simulating super(sub) with Observable.apply(this, [sub])", () => { - function SubclassWithSuperApplyArray(...args: [Subscriber]) { + function SubclassWithSuperApplyArray( + this: ObservableWithSub, + ...args: [Subscriber] + ) { const self = Observable.apply(this, args) || this; self.sub = args[0]; return self; diff --git a/src/utilities/observables/__tests__/asyncMap.ts b/src/utilities/observables/__tests__/asyncMap.ts index e54b2140e66..491686d4f2c 100644 --- a/src/utilities/observables/__tests__/asyncMap.ts +++ b/src/utilities/observables/__tests__/asyncMap.ts @@ -25,6 +25,7 @@ function rejectExceptions( ) { return function () { try { + // @ts-expect-error return fn.apply(this, arguments); } catch (error) { reject(error); diff --git a/src/utilities/policies/pagination.ts b/src/utilities/policies/pagination.ts index 4dd000e32da..acb4c5af6f2 100644 --- a/src/utilities/policies/pagination.ts +++ b/src/utilities/policies/pagination.ts @@ -42,7 +42,7 @@ export function offsetLimitPagination( // to receive any arguments, so you might prefer to throw an // exception here, instead of recovering by appending incoming // onto the existing array. - merged.push.apply(merged, incoming); + merged.push(...incoming); } } diff --git a/src/utilities/subscriptions/relay/index.ts b/src/utilities/subscriptions/relay/index.ts index 94a6c250e19..1c92c074fea 100644 --- a/src/utilities/subscriptions/relay/index.ts +++ b/src/utilities/subscriptions/relay/index.ts @@ -33,7 +33,7 @@ export function createFetchMultipartSubscription( try { options.body = serializeFetchParameter(body, "Payload"); } catch (parseError) { - sink.error(parseError); + sink.error(parseError as Error); } const currentFetch = preferredFetch || maybe(() => fetch) || backupFetch; diff --git a/src/utilities/types/TODO.ts b/src/utilities/types/TODO.ts new file mode 100644 index 00000000000..a5d637cc22c --- /dev/null +++ b/src/utilities/types/TODO.ts @@ -0,0 +1,2 @@ +/** @internal */ +export type TODO = any; diff --git a/tsconfig.json b/tsconfig.json index b03c9fb7fcb..a872c60ff05 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "experimentalDecorators": true, "outDir": "./dist", "lib": ["es2015", "esnext.asynciterable", "dom"], - "jsx": "react" + "jsx": "react", + "strict": true }, "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": ["src/**/__tests__/**/*"] diff --git a/tsconfig.tests.json b/tsconfig.tests.json index d6bb25bd3fd..0908742da0d 100644 --- a/tsconfig.tests.json +++ b/tsconfig.tests.json @@ -1,5 +1,3 @@ { - "extends": "./tsconfig.json", - "include": ["src/**/__tests__/**/*.ts", "src/**/__tests__/**/*.tsx"], - "exclude": [] + "extends": "./src/tsconfig.json" }