apollo-angular
Version:
Use your GraphQL data in your Angular app, with the Apollo Client
415 lines (403 loc) • 13.5 kB
JavaScript
import { Observable, queueScheduler, observable, from } from 'rxjs';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Optional, Inject } from '@angular/core';
import { NetworkStatus, ApolloClient, gql as gql$1 } from '@apollo/client/core';
import { map, startWith, observeOn } from 'rxjs/operators';
function fromPromise(promiseFn) {
return new Observable(subscriber => {
promiseFn().then(result => {
if (!subscriber.closed) {
subscriber.next(result);
subscriber.complete();
}
}, error => {
if (!subscriber.closed) {
subscriber.error(error);
}
});
return () => subscriber.unsubscribe();
});
}
function useMutationLoading(source, enabled) {
if (!enabled) {
return source.pipe(map(result => ({
...result,
loading: false,
})));
}
return source.pipe(startWith({
loading: true,
}), map(result => ({
...result,
loading: !!result.loading,
})));
}
class ZoneScheduler {
zone;
constructor(zone) {
this.zone = zone;
}
now = Date.now ? Date.now : () => +new Date();
schedule(work, delay = 0, state) {
return this.zone.run(() => queueScheduler.schedule(work, delay, state));
}
}
function fixObservable(obs) {
obs[observable] = () => obs;
return obs;
}
function wrapWithZone(obs, ngZone) {
return obs.pipe(observeOn(new ZoneScheduler(ngZone)));
}
function useInitialLoading(obsQuery) {
return function useInitialLoadingOperator(source) {
return new Observable(function useInitialLoadingSubscription(subscriber) {
const currentResult = obsQuery.getCurrentResult();
const { loading, errors, error, partial, data } = currentResult;
const { partialRefetch, fetchPolicy } = obsQuery.options;
const hasError = errors || error;
if (partialRefetch &&
partial &&
(!data || Object.keys(data).length === 0) &&
fetchPolicy !== 'cache-only' &&
!loading &&
!hasError) {
subscriber.next({
...currentResult,
loading: true,
networkStatus: NetworkStatus.loading,
});
}
return source.subscribe(subscriber);
});
};
}
class QueryRef {
obsQuery;
valueChanges;
queryId;
constructor(obsQuery, ngZone, options) {
this.obsQuery = obsQuery;
const wrapped = wrapWithZone(from(fixObservable(this.obsQuery)), ngZone);
this.valueChanges = options.useInitialLoading
? wrapped.pipe(useInitialLoading(this.obsQuery))
: wrapped;
this.queryId = this.obsQuery.queryId;
}
// ObservableQuery's methods
get options() {
return this.obsQuery.options;
}
get variables() {
return this.obsQuery.variables;
}
result() {
return this.obsQuery.result();
}
getCurrentResult() {
return this.obsQuery.getCurrentResult();
}
getLastResult() {
return this.obsQuery.getLastResult();
}
getLastError() {
return this.obsQuery.getLastError();
}
resetLastResults() {
return this.obsQuery.resetLastResults();
}
refetch(variables) {
return this.obsQuery.refetch(variables);
}
fetchMore(fetchMoreOptions) {
return this.obsQuery.fetchMore(fetchMoreOptions);
}
subscribeToMore(options) {
return this.obsQuery.subscribeToMore(options);
}
updateQuery(mapFn) {
return this.obsQuery.updateQuery(mapFn);
}
stopPolling() {
return this.obsQuery.stopPolling();
}
startPolling(pollInterval) {
return this.obsQuery.startPolling(pollInterval);
}
setOptions(opts) {
return this.obsQuery.setOptions(opts);
}
setVariables(variables) {
return this.obsQuery.setVariables(variables);
}
}
const APOLLO_FLAGS = new InjectionToken('APOLLO_FLAGS');
const APOLLO_OPTIONS = new InjectionToken('APOLLO_OPTIONS');
const APOLLO_NAMED_OPTIONS = new InjectionToken('APOLLO_NAMED_OPTIONS');
class ApolloBase {
ngZone;
flags;
_client;
useInitialLoading;
useMutationLoading;
constructor(ngZone, flags, _client) {
this.ngZone = ngZone;
this.flags = flags;
this._client = _client;
this.useInitialLoading = flags?.useInitialLoading ?? false;
this.useMutationLoading = flags?.useMutationLoading ?? false;
}
watchQuery(options) {
return new QueryRef(this.ensureClient().watchQuery({
...options,
}), this.ngZone, {
useInitialLoading: this.useInitialLoading,
...options,
});
}
query(options) {
return fromPromise(() => this.ensureClient().query({ ...options }));
}
mutate(options) {
return useMutationLoading(fromPromise(() => this.ensureClient().mutate({ ...options })), options.useMutationLoading ?? this.useMutationLoading);
}
watchFragment(options, extra) {
const obs = from(fixObservable(this.ensureClient().watchFragment({ ...options })));
return extra && extra.useZone !== true ? obs : wrapWithZone(obs, this.ngZone);
}
subscribe(options, extra) {
const obs = from(fixObservable(this.ensureClient().subscribe({ ...options })));
return extra && extra.useZone !== true ? obs : wrapWithZone(obs, this.ngZone);
}
/**
* Get an instance of ApolloClient
*/
get client() {
return this.ensureClient();
}
/**
* Set a new instance of ApolloClient
* Remember to clean up the store before setting a new client.
*
* @param client ApolloClient instance
*/
set client(client) {
if (this._client) {
throw new Error('Client has been already defined');
}
this._client = client;
}
ensureClient() {
this.checkInstance();
return this._client;
}
checkInstance() {
if (this._client) {
return true;
}
else {
throw new Error('Client has not been defined yet');
}
}
}
class Apollo extends ApolloBase {
map = new Map();
constructor(ngZone, apolloOptions, apolloNamedOptions, flags) {
super(ngZone, flags);
if (apolloOptions) {
this.createDefault(apolloOptions);
}
if (apolloNamedOptions && typeof apolloNamedOptions === 'object') {
for (let name in apolloNamedOptions) {
if (apolloNamedOptions.hasOwnProperty(name)) {
const options = apolloNamedOptions[name];
this.create(options, name);
}
}
}
}
/**
* Create an instance of ApolloClient
* @param options Options required to create ApolloClient
* @param name client's name
*/
create(options, name) {
if (isNamed(name)) {
this.createNamed(name, options);
}
else {
this.createDefault(options);
}
}
/**
* Use a default ApolloClient
*/
default() {
return this;
}
/**
* Use a named ApolloClient
* @param name client's name
*/
use(name) {
if (isNamed(name)) {
return this.map.get(name);
}
else {
return this.default();
}
}
/**
* Create a default ApolloClient, same as `apollo.create(options)`
* @param options ApolloClient's options
*/
createDefault(options) {
if (this._client) {
throw new Error('Apollo has been already created.');
}
this.client = this.ngZone.runOutsideAngular(() => new ApolloClient(options));
}
/**
* Create a named ApolloClient, same as `apollo.create(options, name)`
* @param name client's name
* @param options ApolloClient's options
*/
createNamed(name, options) {
if (this.map.has(name)) {
throw new Error(`Client ${name} has been already created`);
}
this.map.set(name, new ApolloBase(this.ngZone, this.flags, this.ngZone.runOutsideAngular(() => new ApolloClient(options))));
}
/**
* Remember to clean up the store before removing a client
* @param name client's name
*/
removeClient(name) {
if (isNamed(name)) {
this.map.delete(name);
}
else {
this._client = undefined;
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Apollo, deps: [{ token: i0.NgZone }, { token: APOLLO_OPTIONS, optional: true }, { token: APOLLO_NAMED_OPTIONS, optional: true }, { token: APOLLO_FLAGS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Apollo });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Apollo, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i0.NgZone }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [APOLLO_OPTIONS]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [APOLLO_NAMED_OPTIONS]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [APOLLO_FLAGS]
}, {
type: Optional
}] }] });
function isNamed(name) {
return !!name && name !== 'default';
}
function provideApollo(optionsFactory, flags = {}) {
return [
Apollo,
{
provide: APOLLO_OPTIONS,
useFactory: optionsFactory,
},
{
provide: APOLLO_FLAGS,
useValue: flags,
},
];
}
function provideNamedApollo(optionsFactory, flags = {}) {
return [
Apollo,
{
provide: APOLLO_NAMED_OPTIONS,
useFactory: optionsFactory,
},
{
provide: APOLLO_FLAGS,
useValue: flags,
},
];
}
class Query {
apollo;
client = 'default';
constructor(apollo) {
this.apollo = apollo;
}
watch(variables, options) {
return this.apollo.use(this.client).watchQuery({
...options,
variables,
query: this.document,
});
}
fetch(variables, options) {
return this.apollo.use(this.client).query({
...options,
variables,
query: this.document,
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Query, deps: [{ token: Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Query });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Query, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: Apollo }] });
class Mutation {
apollo;
client = 'default';
constructor(apollo) {
this.apollo = apollo;
}
mutate(variables, options) {
return this.apollo.use(this.client).mutate({
...options,
variables,
mutation: this.document,
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Mutation, deps: [{ token: Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Mutation });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Mutation, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: Apollo }] });
class Subscription {
apollo;
client = 'default';
constructor(apollo) {
this.apollo = apollo;
}
subscribe(variables, options, extra) {
return this.apollo.use(this.client).subscribe({
...options,
variables,
query: this.document,
}, extra);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Subscription, deps: [{ token: Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Subscription });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: Subscription, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: Apollo }] });
const typedGQLTag = gql$1;
const gql = typedGQLTag;
/**
* Generated bundle index. Do not edit.
*/
export { APOLLO_FLAGS, APOLLO_NAMED_OPTIONS, APOLLO_OPTIONS, Apollo, ApolloBase, Mutation, Query, QueryRef, Subscription, gql, provideApollo, provideNamedApollo };
//# sourceMappingURL=ngApollo.mjs.map