Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 1x 12x 12x 12x 12x 2x 2x 3x 3x 3x 3x 3x 2x 2x 4x 4x 5x 5x 5x 3x | import { inject, Injectable } from '@angular/core';
import { ApolloClient, ApolloClientOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client/core';
import { AppHttpHandlersService, TGqlClient } from '@app/client-store-http-progress';
import { IUserState, userSelector } from '@app/client-store-user';
import { Store } from '@ngrx/store';
import { Apollo } from 'apollo-angular';
import { DocumentNode } from 'graphql';
import { from, Observable, of } from 'rxjs';
import { first, map, switchMap, tap } from 'rxjs/operators';
/**
* Client Graphql service.
*/
@Injectable({
providedIn: 'root',
})
export class AppGqlService {
private readonly apollo = inject(Apollo);
private readonly handlers = inject(AppHttpHandlersService);
private readonly store = inject(Store<IUserState>);
private readonly userToken$ = this.store.select(userSelector.token).pipe(first());
/**
* Creates apollo client for a specific user role.
* @param name the client name
*/
public createApolloClient(name: TGqlClient = 'graphql'): Observable<ApolloClientOptions<NormalizedCacheObject>> {
return this.getApolloClientOptions(name).pipe(
tap(options => {
this.apollo.create(options, name);
}),
);
}
/**
* Resets apollo client for a specific user role.
* @param name the client name
*/
public resetApolloClient(name: TGqlClient = 'graphql') {
return this.getApolloClientOptions(name).pipe(
switchMap(options => {
const newClient = new ApolloClient(options);
const client = this.apollo.use(name).client as ApolloClient<NormalizedCacheObject> | undefined;
return this.clearClient(client).pipe(
tap(() => {
this.apollo.use(name).client = newClient;
}),
);
}),
);
}
/**
* Gql query - a read-only fetch.
* @param query the quesry
* @param name the client name
* @param variables the query arguments
*/
public query<T>(query: DocumentNode, name: TGqlClient = 'graphql', variables: Record<string, unknown> = {}) {
const observable = this.apollo.use(name).watchQuery<T>({
query,
variables,
fetchPolicy: 'no-cache',
}).valueChanges;
return this.handlers.pipeGqlResponse<T>(observable);
}
/**
* Gql mutation - a write followed by a fetch.
* @param mutation the muration
* @param name the client name
* @param variables the mutation arguments
*/
public mutate<T>(mutation: DocumentNode, name: TGqlClient = 'graphql', variables: Record<string, unknown> = {}) {
const observable = this.apollo.use(name).mutate<T>({
mutation,
variables,
fetchPolicy: 'no-cache',
});
return this.handlers.pipeGqlResponse<T>(observable);
}
/**
* Returns apollo client options depending on user role.
* @param name the client name
*/
private getApolloClientOptions(name: TGqlClient): Observable<ApolloClientOptions<NormalizedCacheObject>> {
return this.userToken$.pipe(
map(token => this.handlers.createGqlLink(token, name)),
map(link => {
const options: ApolloClientOptions<NormalizedCacheObject> = {
link,
cache: new InMemoryCache({ resultCaching: false }),
defaultOptions: {
query: {
errorPolicy: 'all',
},
watchQuery: {
errorPolicy: 'all',
},
mutate: {
errorPolicy: 'all',
},
},
};
return options;
}),
);
}
/**
* Clears apollo client.
* @param client apollo client
*/
private clearClient(client?: ApolloClient<NormalizedCacheObject>) {
return typeof client !== 'undefined' ? from(client.resetStore()) : of(null);
}
}
|