@apollo-orbit/angular
Version:
A fully-featured GraphQL client for Angular with modular state management.
382 lines (369 loc) • 14.4 kB
JavaScript
import * as i1 from '@apollo/client/core';
import { ApolloError, NetworkStatus, ApolloClient } from '@apollo/client/core';
export { ApolloCache, ApolloClient, ApolloError, Cache, InMemoryCache, NetworkStatus, gql } from '@apollo/client/core';
import * as i0 from '@angular/core';
import { Injectable, InjectionToken, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, inject } from '@angular/core';
import { Observable, defer, of } from 'rxjs';
import { map, startWith, catchError } from 'rxjs/operators';
function extendCache(cache) {
return Object.defineProperties(cache, {
watchQuery: {
value: watchQuery,
writable: false,
configurable: false
}
});
}
function watchQuery(options) {
const { immediate = true, optimistic = true } = options;
return new Observable(subscriber => this.watch({
...options,
optimistic,
immediate,
callback: ({ result, ...rest }) => subscriber.next({ ...rest, data: result })
}));
}
function toQueryResult({ errors, ...result }) {
return {
...result,
error: getApolloError(errors, result.error)
};
}
function toMutationResult(fetchResult, apolloError) {
fetchResult ??= {};
const { errors, data, extensions } = fetchResult;
const context = 'context' in fetchResult ? fetchResult.context : undefined;
return {
data: data ?? undefined,
error: getApolloError(errors, apolloError),
context,
extensions
};
}
function toSubscriptionResult(fetchResult) {
return toMutationResult(fetchResult);
}
function getApolloError(graphQLErrors, apolloError) {
return graphQLErrors && graphQLErrors.length > 0 ? new ApolloError({ graphQLErrors }) : apolloError;
}
class QueryObservable extends Observable {
observableQuery;
previousData;
constructor(observableQuery, { notifyOnLoading = true, throwError = false }) {
super(subscriber => {
let subscription;
if (notifyOnLoading) {
// on calling getCurrentResult apollo client sets lastResult based on fetchPolicy
// when lastResult is present, apollo client emits value on subscription
// otherwise, it is emitted here instead
const currentResult = this.getCurrentResult();
const lastResult = observableQuery.getLastResult();
if (!lastResult) {
const { previousData } = this;
subscriber.next({ ...currentResult, previousData });
this.previousData = currentResult.data ?? previousData;
}
}
const observer = {
next: () => {
const currentResult = this.getCurrentResult();
const { previousData } = this;
subscriber.next({ ...currentResult, previousData });
this.previousData = currentResult.data ?? previousData;
},
error: error => {
subscription = undefined;
if (throwError) {
subscriber.error(error);
}
else {
const currentResult = this.getCurrentResult();
const { previousData } = this;
subscriber.next({ ...currentResult, previousData });
this.previousData = currentResult.data ?? previousData;
subscription = observableQuery.resubscribeAfterError(observer);
}
},
complete: () => {
subscription = undefined;
subscriber.complete();
}
};
subscription = observableQuery.subscribe(observer);
return () => subscription?.unsubscribe();
});
this.observableQuery = observableQuery;
}
get query() {
return this.observableQuery.query;
}
get variables() {
return this.observableQuery.variables;
}
get options() {
return this.observableQuery.options;
}
get queryId() {
return this.observableQuery.queryId;
}
get queryName() {
return this.observableQuery.queryName;
}
result() {
return this.observableQuery.result();
}
getCurrentResult(saveAsLastResult = true) {
return toQueryResult(this.observableQuery.getCurrentResult(saveAsLastResult));
}
// Compares newResult to the snapshot we took of this.lastResult when it was
// first received.
isDifferentFromLastResult(newResult, variables) {
return this.observableQuery.isDifferentFromLastResult(newResult, variables);
}
getLastResult(variablesMustMatch) {
return this.observableQuery.getLastResult(variablesMustMatch);
}
getLastError(variablesMustMatch) {
return this.observableQuery.getLastError(variablesMustMatch);
}
resetLastResults() {
this.observableQuery.resetLastResults();
}
resetQueryStoreErrors() {
this.observableQuery.resetQueryStoreErrors();
}
/**
* Update the variables of this observable query, and fetch the new results.
* This method should be preferred over `setVariables` in most use cases.
*
* @param variables: The new set of variables. If there are missing variables,
* the previous values of those variables will be used.
*/
refetch(variables) {
return this.observableQuery.refetch(variables);
}
fetchMore(fetchMoreOptions) {
return this.observableQuery.fetchMore(fetchMoreOptions);
}
subscribeToMore(options) {
const { query: document, ...rest } = options;
return this.observableQuery.subscribeToMore({ document, ...rest });
}
setOptions(newOptions) {
return this.observableQuery.setOptions(newOptions);
}
silentSetOptions(newOptions) {
this.observableQuery.silentSetOptions(newOptions);
}
/**
* Update the variables of this observable query, and fetch the new results
* if they've changed. Most users should prefer `refetch` instead of
* `setVariables` in order to to be properly notified of results even when
* they come from the cache.
*
* Note: the `next` callback will *not* fire if the variables have not changed
* or if the result is coming from cache.
*
* Note: the promise will return the old results immediately if the variables
* have not changed.
*
* Note: the promise will return null immediately if the query is not active
* (there are no subscribers).
*
* @private
*
* @param variables: The new set of variables. If there are missing variables,
* the previous values of those variables will be used.
*/
setVariables(variables) {
return this.observableQuery.setVariables(variables);
}
updateQuery(mapFn) {
return this.observableQuery.updateQuery(mapFn);
}
startPolling(pollInterval) {
this.observableQuery.startPolling(pollInterval);
}
stopPolling() {
return this.observableQuery.stopPolling();
}
reobserveAsConcast(newOptions, newNetworkStatus) {
return this.observableQuery.reobserveAsConcast(newOptions, newNetworkStatus);
}
reobserve(newOptions, newNetworkStatus) {
return this.observableQuery.reobserve(newOptions, newNetworkStatus);
}
resubscribeAfterError(...args) {
return this.observableQuery.resubscribeAfterError(...args);
}
hasObservers() {
return this.observableQuery.hasObservers();
}
}
const fromZenObservable = (source) => new Observable(source.subscribe.bind(source));
/* eslint-disable max-len */
class Apollo {
/**
* Instance of ApolloClient
*/
client;
defaultOptions;
_cache;
constructor(client, defaultOptions) {
this.client = client;
this.defaultOptions = defaultOptions;
this._cache = extendCache(client.cache);
}
query(options) {
const { notifyOnLoading = false, throwError = true } = { ...this.defaultOptions?.query, ...options };
return defer(() => this.client.query(options)).pipe(map(result => toQueryResult(result)), (source => notifyOnLoading
? source.pipe(startWith({ loading: true, networkStatus: NetworkStatus.loading }))
: source), (source => !throwError
? source.pipe(catchError((error) => of({ error, loading: false, networkStatus: NetworkStatus.error })))
: source));
}
watchQuery(options) {
const { notifyOnLoading, throwError } = { ...this.defaultOptions?.watchQuery, ...options };
return new QueryObservable(this.client.watchQuery(options), { notifyOnLoading, throwError });
}
watchFragment(options) {
return fromZenObservable(this.client.watchFragment(options));
}
mutate(options) {
return defer(() => this.client.mutate(options)).pipe(map(result => toMutationResult(result)));
}
subscribe(options) {
return defer(() => fromZenObservable(this.client.subscribe(options))).pipe(map(result => toSubscriptionResult(result)));
}
get cache() {
return this._cache;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: Apollo, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: Apollo });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: Apollo, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.ApolloClient }, { type: undefined }] });
const APOLLO_CLIENT_FACTORY = new InjectionToken('[apollo-orbit] client factory');
const apolloClientFactory = (options) => {
return new ApolloClient(options);
};
function mapQuery(fn) {
return (observable) => observable.pipe(map((result) => {
const { data, previousData, ...rest } = result;
return {
...rest,
data: data !== undefined ? fn(data) : undefined,
previousData: previousData !== undefined ? fn(previousData) : undefined
};
}));
}
function mapMutation(fn) {
return (observable) => observable.pipe(map((result) => {
const { data, ...rest } = result;
return {
...rest,
data: data !== undefined ? fn(data) : undefined
};
}));
}
function mapSubscription(fn) {
return (observable) => observable.pipe(map((result) => {
const { data, ...rest } = result;
return {
...rest,
data: data !== undefined ? fn(data) : undefined
};
}));
}
const APOLLO_PROVIDED = new InjectionToken('[apollo-orbit] apollo provided');
const APOLLO_MULTI_ROOT = new InjectionToken('[apollo-orbit] multi root');
const APOLLO_INSTANCE_FACTORY = new InjectionToken('[apollo-orbit] apollo instance factory');
const APOLLO_ORBIT_PROVIDERS = [
[
{ provide: Apollo, useFactory: () => apolloFactory(null) }, // guard
{ provide: APOLLO_PROVIDED, useValue: true },
{ provide: APOLLO_INSTANCE_FACTORY, useFactory: apolloInstanceFactory },
{ provide: APOLLO_CLIENT_FACTORY, useValue: apolloClientFactory }
]
];
function withApolloOptions(options) {
return {
kind: 'APOLLO_ORBIT_OPTIONS',
providers: getApolloInstanceProviders(Apollo, options)
};
}
function provideApolloOrbit(...features) {
return makeEnvironmentProviders([
...APOLLO_ORBIT_PROVIDERS,
features.map(({ providers }) => providers),
{ provide: ENVIRONMENT_INITIALIZER, multi: true, useFactory: () => apolloOrbitRootGuard }
]);
}
function provideApolloInstance(token, options) {
return makeEnvironmentProviders(getApolloInstanceProviders(token, options));
}
function getApolloInstanceProviders(token, options) {
return [
typeof options === 'function'
? {
provide: token,
useFactory: () => apolloFactory(options())
}
: {
provide: token,
useFactory: () => apolloFactory(options)
}
];
}
function apolloInstanceFactory() {
return (_clientId, client, defaultOptions) => new Apollo(client, defaultOptions);
}
function apolloFactory(options) {
if (!options)
throw new Error('withApolloOptions feature must be passed to provideApolloOrbit() before injecting Apollo');
const { id = 'default', cache, defaultOptions, ...rest } = options;
const createClient = inject(APOLLO_CLIENT_FACTORY);
const client = createClient({ cache, defaultOptions, ...rest });
return inject(APOLLO_INSTANCE_FACTORY)(id, client, defaultOptions);
}
function apolloOrbitRootGuard() {
const isProvided = inject(APOLLO_PROVIDED, { optional: true, skipSelf: true });
const multiRoot = inject(APOLLO_MULTI_ROOT, { optional: true });
if (isProvided && multiRoot !== true) {
throw new Error('provideApolloOrbit() has been called more than once. Consider calling provideStates() instead. Otherwise, you may provide APOLLO_MULTI_ROOT token.');
}
}
class PureQueryOptions {
query;
variables;
context;
constructor(query, variables, context) {
this.query = query;
this.variables = variables;
this.context = context;
}
}
class PureMutationOptions {
mutation;
variables;
context;
constructor(mutation, variables, context) {
this.mutation = mutation;
this.variables = variables;
this.context = context;
}
}
class PureSubscriptionOptions {
query;
variables;
constructor(query, variables) {
this.query = query;
this.variables = variables;
}
}
/**
* Generated bundle index. Do not edit.
*/
export { APOLLO_CLIENT_FACTORY, APOLLO_MULTI_ROOT, Apollo, PureMutationOptions, PureQueryOptions, PureSubscriptionOptions, QueryObservable, mapMutation, mapQuery, mapSubscription, provideApolloInstance, provideApolloOrbit, withApolloOptions, APOLLO_INSTANCE_FACTORY as ɵAPOLLO_INSTANCE_FACTORY };
//# sourceMappingURL=apollo-orbit.angular.core.mjs.map