New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

apollo-client

Package Overview
Dependencies
Maintainers
7
Versions
309
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-client - npm Package Compare versions

Comparing version 2.2.7 to 2.2.8

153

ApolloClient.d.ts

@@ -24,2 +24,8 @@ import { ApolloLink, FetchResult, GraphQLRequest } from 'apollo-link';

};
/**
* This is the primary Apollo Client class. It is used to send GraphQL documents (i.e. queries
* and mutations) to a GraphQL spec-compliant server over a {@link NetworkInterface} instance,
* receive results from the server and cache the results in a store. It also delivers updates
* to GraphQL queries through {@link Observable} instances.
*/
export default class ApolloClient<TCacheShape> implements DataProxy {

@@ -38,21 +44,168 @@ link: ApolloLink;

private resetStoreCallbacks;
/**
* Constructs an instance of {@link ApolloClient}.
*
* @param link The {@link ApolloLink} over which GraphQL documents will be resolved into a response.
*
* @param cache The initial cache to use in the data store.
*
* @param ssrMode Determines whether this is being run in Server Side Rendering (SSR) mode.
*
* @param ssrForceFetchDelay Determines the time interval before we force fetch queries for a
* server side render.
*
* @param queryDeduplication If set to false, a query will still be sent to the server even if a query
* with identical parameters (query, variables, operationName) is already in flight.
*
*/
constructor(options: ApolloClientOptions<TCacheShape>);
/**
* This watches the results of the query according to the options specified and
* returns an {@link ObservableQuery}. We can subscribe to this {@link ObservableQuery} and
* receive updated results through a GraphQL observer.
* <p /><p />
* Note that this method is not an implementation of GraphQL subscriptions. Rather,
* it uses Apollo's store in order to reactively deliver updates to your query results.
* <p /><p />
* For example, suppose you call watchQuery on a GraphQL query that fetches an person's
* first name and last name and this person has a particular object identifer, provided by
* dataIdFromObject. Later, a different query fetches that same person's
* first and last name and his/her first name has now changed. Then, any observers associated
* with the results of the first query will be updated with a new result object.
* <p /><p />
* See [here](https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.3mb0cbcmc) for
* a description of store reactivity.
*
*/
watchQuery<T>(options: WatchQueryOptions): ObservableQuery<T>;
/**
* This resolves a single query according to the options specified and returns a
* {@link Promise} which is either resolved with the resulting data or rejected
* with an error.
*
* @param options An object of type {@link WatchQueryOptions} that allows us to describe
* how this query should be treated e.g. whether it is a polling query, whether it should hit the
* server at all or just resolve from the cache, etc.
*/
query<T>(options: WatchQueryOptions): Promise<ApolloQueryResult<T>>;
/**
* This resolves a single mutation according to the options specified and returns a
* {@link Promise} which is either resolved with the resulting data or rejected with an
* error.
*
* It takes options as an object with the following keys and values:
*/
mutate<T>(options: MutationOptions<T>): Promise<FetchResult<T>>;
/**
* This subscribes to a graphql subscription according to the options specified and returns an
* {@link Observable} which either emits received data or an error.
*/
subscribe<T = any>(options: SubscriptionOptions): Observable<T>;
/**
* Tries to read some data from the store in the shape of the provided
* GraphQL query without making a network request. This method will start at
* the root query. To start at a specific id returned by `dataIdFromObject`
* use `readFragment`.
*/
readQuery<T>(options: DataProxy.Query): T | null;
/**
* Tries to read some data from the store in the shape of the provided
* GraphQL fragment without making a network request. This method will read a
* GraphQL fragment from any arbitrary id that is currently cached, unlike
* `readQuery` which will only read from the root query.
*
* You must pass in a GraphQL document with a single fragment or a document
* with multiple fragments that represent what you are reading. If you pass
* in a document with multiple fragments then you must also specify a
* `fragmentName`.
*/
readFragment<T>(options: DataProxy.Fragment): T | null;
/**
* Writes some data in the shape of the provided GraphQL query directly to
* the store. This method will start at the root query. To start at a a
* specific id returned by `dataIdFromObject` then use `writeFragment`.
*/
writeQuery(options: DataProxy.WriteQueryOptions): void;
/**
* Writes some data in the shape of the provided GraphQL fragment directly to
* the store. This method will write to a GraphQL fragment from any arbitrary
* id that is currently cached, unlike `writeQuery` which will only write
* from the root query.
*
* You must pass in a GraphQL document with a single fragment or a document
* with multiple fragments that represent what you are writing. If you pass
* in a document with multiple fragments then you must also specify a
* `fragmentName`.
*/
writeFragment(options: DataProxy.WriteFragmentOptions): void;
/**
* Sugar for writeQuery & writeFragment
* This method will construct a query from the data object passed in.
* If no id is supplied, writeData will write the data to the root.
* If an id is supplied, writeData will write a fragment to the object
* specified by the id in the store.
*
* Since you aren't passing in a query to check the shape of the data,
* you must pass in an object that conforms to the shape of valid GraphQL data.
*/
writeData(options: DataProxy.WriteDataOptions): void;
__actionHookForDevTools(cb: () => any): void;
__requestRaw(payload: GraphQLRequest): Observable<ExecutionResult>;
/**
* This initializes the query manager that tracks queries and the cache
*/
initQueryManager(): void;
/**
* Resets your entire store by clearing out your cache and then re-executing
* all of your active queries. This makes it so that you may guarantee that
* there is no data left in your store from a time before you called this
* method.
*
* `resetStore()` is useful when your user just logged out. You’ve removed the
* user session, and you now want to make sure that any references to data you
* might have fetched while the user session was active is gone.
*
* It is important to remember that `resetStore()` *will* refetch any active
* queries. This means that any components that might be mounted will execute
* their queries again using your network interface. If you do not want to
* re-execute any queries then you should make sure to stop watching any
* active queries.
*/
resetStore(): Promise<ApolloQueryResult<any>[] | null>;
/**
* Allows callbacks to be registered that are executed with the store is reset.
* onResetStore returns an unsubscribe function for removing your registered callbacks.
*/
onResetStore(cb: () => Promise<any>): () => void;
/**
* Refetches all of your active queries.
*
* `reFetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage
*
* It is important to remember that `reFetchObservableQueries()` *will* refetch any active
* queries. This means that any components that might be mounted will execute
* their queries again using your network interface. If you do not want to
* re-execute any queries then you should make sure to stop watching any
* active queries.
* Takes optional parameter `includeStandby` which will include queries in standby-mode when refetching.
*/
reFetchObservableQueries(includeStandby?: boolean): Promise<ApolloQueryResult<any>[]> | Promise<null>;
/**
* Exposes the cache's complete state, in a serializable format for later restoration.
*/
extract(optimistic?: boolean): TCacheShape;
/**
* Replaces existing state in the cache (if any) with the values expressed by
* `serializedState`.
*
* Called when hydrating a cache (server side rendering, or offline storage),
* and also (potentially) during hot reloads.
*/
restore(serializedState: TCacheShape): ApolloCache<TCacheShape>;
/**
* Initializes a data proxy for this client instance if one does not already
* exist and returns either a previously initialized proxy instance or the
* newly initialized instance.
*/
private initProxy();
}

166

ApolloClient.js

@@ -19,3 +19,25 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {

});
/**
* This is the primary Apollo Client class. It is used to send GraphQL documents (i.e. queries
* and mutations) to a GraphQL spec-compliant server over a {@link NetworkInterface} instance,
* receive results from the server and cache the results in a store. It also delivers updates
* to GraphQL queries through {@link Observable} instances.
*/
var ApolloClient = (function () {
/**
* Constructs an instance of {@link ApolloClient}.
*
* @param link The {@link ApolloLink} over which GraphQL documents will be resolved into a response.
*
* @param cache The initial cache to use in the data store.
*
* @param ssrMode Determines whether this is being run in Server Side Rendering (SSR) mode.
*
* @param ssrForceFetchDelay Determines the time interval before we force fetch queries for a
* server side render.
*
* @param queryDeduplication If set to false, a query will still be sent to the server even if a query
* with identical parameters (query, variables, operationName) is already in flight.
*
*/
function ApolloClient(options) {

@@ -29,2 +51,3 @@ var _this = this;

}
// remove apollo-client supported directives
this.link = supportedDirectives.concat(link);

@@ -45,2 +68,4 @@ this.cache = cache;

this.reFetchObservableQueries = this.reFetchObservableQueries.bind(this);
// Attach the client instance to window to let us be found by chrome devtools, but only in
// development mode
var defaultConnectToDevTools = !isProduction() &&

@@ -54,2 +79,5 @@ typeof window !== 'undefined' &&

}
/**
* Suggest installing the devtools for developers who don't have them
*/
if (!hasSuggestedDevtools && !isProduction()) {

@@ -60,4 +88,7 @@ hasSuggestedDevtools = true;

window.top === window.self) {
// First check if devtools is not installed
if (typeof window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
if (navigator.userAgent.indexOf('Chrome') > -1) {
// Only for Chrome
if (window.navigator && window.navigator.userAgent.indexOf('Chrome') > -1) {
// tslint:disable-next-line
console.debug('Download the Apollo DevTools ' +

@@ -72,2 +103,20 @@ 'for a better development experience: ' +

}
/**
* This watches the results of the query according to the options specified and
* returns an {@link ObservableQuery}. We can subscribe to this {@link ObservableQuery} and
* receive updated results through a GraphQL observer.
* <p /><p />
* Note that this method is not an implementation of GraphQL subscriptions. Rather,
* it uses Apollo's store in order to reactively deliver updates to your query results.
* <p /><p />
* For example, suppose you call watchQuery on a GraphQL query that fetches an person's
* first name and last name and this person has a particular object identifer, provided by
* dataIdFromObject. Later, a different query fetches that same person's
* first and last name and his/her first name has now changed. Then, any observers associated
* with the results of the first query will be updated with a new result object.
* <p /><p />
* See [here](https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.3mb0cbcmc) for
* a description of store reactivity.
*
*/
ApolloClient.prototype.watchQuery = function (options) {

@@ -78,2 +127,3 @@ this.initQueryManager();

}
// XXX Overwriting options is probably not the best way to do this long term...
if (this.disableNetworkFetches && options.fetchPolicy === 'network-only') {

@@ -84,2 +134,11 @@ options = __assign({}, options, { fetchPolicy: 'cache-first' });

};
/**
* This resolves a single query according to the options specified and returns a
* {@link Promise} which is either resolved with the resulting data or rejected
* with an error.
*
* @param options An object of type {@link WatchQueryOptions} that allows us to describe
* how this query should be treated e.g. whether it is a polling query, whether it should hit the
* server at all or just resolve from the cache, etc.
*/
ApolloClient.prototype.query = function (options) {

@@ -93,2 +152,3 @@ this.initQueryManager();

}
// XXX Overwriting options is probably not the best way to do this long term...
if (this.disableNetworkFetches && options.fetchPolicy === 'network-only') {

@@ -99,2 +159,9 @@ options = __assign({}, options, { fetchPolicy: 'cache-first' });

};
/**
* This resolves a single mutation according to the options specified and returns a
* {@link Promise} which is either resolved with the resulting data or rejected with an
* error.
*
* It takes options as an object with the following keys and values:
*/
ApolloClient.prototype.mutate = function (options) {

@@ -107,2 +174,6 @@ this.initQueryManager();

};
/**
* This subscribes to a graphql subscription according to the options specified and returns an
* {@link Observable} which either emits received data or an error.
*/
ApolloClient.prototype.subscribe = function (options) {

@@ -112,8 +183,30 @@ this.initQueryManager();

};
/**
* Tries to read some data from the store in the shape of the provided
* GraphQL query without making a network request. This method will start at
* the root query. To start at a specific id returned by `dataIdFromObject`
* use `readFragment`.
*/
ApolloClient.prototype.readQuery = function (options) {
return this.initProxy().readQuery(options);
};
/**
* Tries to read some data from the store in the shape of the provided
* GraphQL fragment without making a network request. This method will read a
* GraphQL fragment from any arbitrary id that is currently cached, unlike
* `readQuery` which will only read from the root query.
*
* You must pass in a GraphQL document with a single fragment or a document
* with multiple fragments that represent what you are reading. If you pass
* in a document with multiple fragments then you must also specify a
* `fragmentName`.
*/
ApolloClient.prototype.readFragment = function (options) {
return this.initProxy().readFragment(options);
};
/**
* Writes some data in the shape of the provided GraphQL query directly to
* the store. This method will start at the root query. To start at a a
* specific id returned by `dataIdFromObject` then use `writeFragment`.
*/
ApolloClient.prototype.writeQuery = function (options) {

@@ -124,2 +217,13 @@ var result = this.initProxy().writeQuery(options);

};
/**
* Writes some data in the shape of the provided GraphQL fragment directly to
* the store. This method will write to a GraphQL fragment from any arbitrary
* id that is currently cached, unlike `writeQuery` which will only write
* from the root query.
*
* You must pass in a GraphQL document with a single fragment or a document
* with multiple fragments that represent what you are writing. If you pass
* in a document with multiple fragments then you must also specify a
* `fragmentName`.
*/
ApolloClient.prototype.writeFragment = function (options) {

@@ -130,2 +234,12 @@ var result = this.initProxy().writeFragment(options);

};
/**
* Sugar for writeQuery & writeFragment
* This method will construct a query from the data object passed in.
* If no id is supplied, writeData will write the data to the root.
* If an id is supplied, writeData will write a fragment to the object
* specified by the id in the store.
*
* Since you aren't passing in a query to check the shape of the data,
* you must pass in an object that conforms to the shape of valid GraphQL data.
*/
ApolloClient.prototype.writeData = function (options) {

@@ -142,2 +256,5 @@ var result = this.initProxy().writeData(options);

};
/**
* This initializes the query manager that tracks queries and the cache
*/
ApolloClient.prototype.initQueryManager = function () {

@@ -166,2 +283,18 @@ var _this = this;

};
/**
* Resets your entire store by clearing out your cache and then re-executing
* all of your active queries. This makes it so that you may guarantee that
* there is no data left in your store from a time before you called this
* method.
*
* `resetStore()` is useful when your user just logged out. You’ve removed the
* user session, and you now want to make sure that any references to data you
* might have fetched while the user session was active is gone.
*
* It is important to remember that `resetStore()` *will* refetch any active
* queries. This means that any components that might be mounted will execute
* their queries again using your network interface. If you do not want to
* re-execute any queries then you should make sure to stop watching any
* active queries.
*/
ApolloClient.prototype.resetStore = function () {

@@ -182,2 +315,6 @@ var _this = this;

};
/**
* Allows callbacks to be registered that are executed with the store is reset.
* onResetStore returns an unsubscribe function for removing your registered callbacks.
*/
ApolloClient.prototype.onResetStore = function (cb) {

@@ -190,2 +327,14 @@ var _this = this;

};
/**
* Refetches all of your active queries.
*
* `reFetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage
*
* It is important to remember that `reFetchObservableQueries()` *will* refetch any active
* queries. This means that any components that might be mounted will execute
* their queries again using your network interface. If you do not want to
* re-execute any queries then you should make sure to stop watching any
* active queries.
* Takes optional parameter `includeStandby` which will include queries in standby-mode when refetching.
*/
ApolloClient.prototype.reFetchObservableQueries = function (includeStandby) {

@@ -196,8 +345,23 @@ return this.queryManager

};
/**
* Exposes the cache's complete state, in a serializable format for later restoration.
*/
ApolloClient.prototype.extract = function (optimistic) {
return this.initProxy().extract(optimistic);
};
/**
* Replaces existing state in the cache (if any) with the values expressed by
* `serializedState`.
*
* Called when hydrating a cache (server side rendering, or offline storage),
* and also (potentially) during hot reloads.
*/
ApolloClient.prototype.restore = function (serializedState) {
return this.initProxy().restore(serializedState);
};
/**
* Initializes a data proxy for this client instance if one does not already
* exist and returns either a previously initialized proxy instance or the
* newly initialized instance.
*/
ApolloClient.prototype.initProxy = function () {

@@ -204,0 +368,0 @@ if (!this.proxy) {

@@ -0,10 +1,45 @@

/**
* The current status of a query’s execution in our system.
*/
export declare enum NetworkStatus {
/**
* The query has never been run before and the query is now currently running. A query will still
* have this network status even if a partial data result was returned from the cache, but a
* query was dispatched anyway.
*/
loading = 1,
/**
* If `setVariables` was called and a query was fired because of that then the network status
* will be `setVariables` until the result of that query comes back.
*/
setVariables = 2,
/**
* Indicates that `fetchMore` was called on this query and that the query created is currently in
* flight.
*/
fetchMore = 3,
/**
* Similar to the `setVariables` network status. It means that `refetch` was called on a query
* and the refetch request is currently in flight.
*/
refetch = 4,
/**
* Indicates that a polling query is currently in flight. So for example if you are polling a
* query every 10 seconds then the network status will switch to `poll` every 10 seconds whenever
* a poll request has been sent but not resolved.
*/
poll = 6,
/**
* No request is in flight for this query, and no errors happened. Everything is OK.
*/
ready = 7,
/**
* No request is in flight for this query, but one or more errors were detected.
*/
error = 8,
}
/**
* Returns true if there is currently a network request in flight according to a given network
* status.
*/
export declare function isNetworkRequestInFlight(networkStatus: NetworkStatus): boolean;

@@ -0,11 +1,46 @@

/**
* The current status of a query’s execution in our system.
*/
export var NetworkStatus;
(function (NetworkStatus) {
/**
* The query has never been run before and the query is now currently running. A query will still
* have this network status even if a partial data result was returned from the cache, but a
* query was dispatched anyway.
*/
NetworkStatus[NetworkStatus["loading"] = 1] = "loading";
/**
* If `setVariables` was called and a query was fired because of that then the network status
* will be `setVariables` until the result of that query comes back.
*/
NetworkStatus[NetworkStatus["setVariables"] = 2] = "setVariables";
/**
* Indicates that `fetchMore` was called on this query and that the query created is currently in
* flight.
*/
NetworkStatus[NetworkStatus["fetchMore"] = 3] = "fetchMore";
/**
* Similar to the `setVariables` network status. It means that `refetch` was called on a query
* and the refetch request is currently in flight.
*/
NetworkStatus[NetworkStatus["refetch"] = 4] = "refetch";
/**
* Indicates that a polling query is currently in flight. So for example if you are polling a
* query every 10 seconds then the network status will switch to `poll` every 10 seconds whenever
* a poll request has been sent but not resolved.
*/
NetworkStatus[NetworkStatus["poll"] = 6] = "poll";
/**
* No request is in flight for this query, and no errors happened. Everything is OK.
*/
NetworkStatus[NetworkStatus["ready"] = 7] = "ready";
/**
* No request is in flight for this query, but one or more errors were detected.
*/
NetworkStatus[NetworkStatus["error"] = 8] = "error";
})(NetworkStatus || (NetworkStatus = {}));
/**
* Returns true if there is currently a network request in flight according to a given network
* status.
*/
export function isNetworkRequestInFlight(networkStatus) {

@@ -12,0 +47,0 @@ return networkStatus < 7;

@@ -36,2 +36,6 @@ import { GraphQLError } from 'graphql';

queryId: string;
/**
*
* The current value of the variables for this query. Can change.
*/
variables: {

@@ -56,2 +60,8 @@ [key: string]: any;

result(): Promise<ApolloQueryResult<T>>;
/**
* Return the result of the query from the local cache as well as some fetching status
* `loading` and `networkStatus` allow to know if a request is in flight
* `partial` lets you know if the result from the local cache is complete or partial
* @return {result: Object, loading: boolean, networkStatus: number, partial: boolean}
*/
currentResult(): ApolloCurrentResult<T>;

@@ -65,2 +75,22 @@ getLastResult(): ApolloQueryResult<T>;

setOptions(opts: ModifiableWatchQueryOptions): Promise<ApolloQueryResult<T>>;
/**
* Update the variables of this observable query, and fetch the new results
* if they've changed. If you want to force new results, use `refetch`.
*
* Note: if the variables have not changed, the promise will return the old
* results immediately, and the `next` callback will *not* fire.
*
* Note: if the query is not active (there are no subscribers), the promise
* will return null immediately.
*
* @param variables: The new set of variables. If there are missing variables,
* the previous values of those variables will be used.
*
* @param tryFetch: Try and fetch new results even if the variables haven't
* changed (we may still just hit the store, but if there's nothing in there
* this will refetch)
*
* @param fetchResults: Option to ignore fetching results when updating variables
*
*/
setVariables(variables: any, tryFetch?: boolean, fetchResults?: boolean): Promise<ApolloQueryResult<T>>;

@@ -67,0 +97,0 @@ updateQuery(mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any): void;

@@ -39,4 +39,6 @@ var __extends = (this && this.__extends) || (function () {

}) || this;
// active state
_this.isCurrentlyPolling = false;
_this.isTornDown = false;
// query information
_this.options = options;

@@ -46,4 +48,6 @@ _this.variables = options.variables || {};

_this.shouldSubscribe = shouldSubscribe;
// related classes
_this.scheduler = scheduler;
_this.queryManager = scheduler.queryManager;
// interal data stores
_this.observers = [];

@@ -60,2 +64,12 @@ _this.subscriptionHandles = [];

resolve(result);
// Stop the query within the QueryManager if we can before
// this function returns.
//
// We do this in order to prevent observers piling up within
// the QueryManager. Notice that we only fully unsubscribe
// from the subscription in a setTimeout(..., 0) call. This call can
// actually be handled by the browser at a much later time. If queries
// are fired in the meantime, observers that should have been removed
// from the QueryManager will continue to fire, causing an unnecessary
// performance hit.
if (!that.observers.some(function (obs) { return obs !== observer; })) {

@@ -75,2 +89,8 @@ that.queryManager.removeQuery(that.queryId);

};
/**
* Return the result of the query from the local cache as well as some fetching status
* `loading` and `networkStatus` allow to know if a request is in flight
* `partial` lets you know if the result from the local cache is complete or partial
* @return {result: Object, loading: boolean, networkStatus: number, partial: boolean}
*/
ObservableQuery.prototype.currentResult = function () {

@@ -100,4 +120,12 @@ if (this.isTornDown) {

queryStoreValue.networkStatus === NetworkStatus.loading;
// We need to be careful about the loading state we show to the user, to try
// and be vaguely in line with what the user would have seen from .subscribe()
// but to still provide useful information synchronously when the query
// will not end up hitting the server.
// See more: https://github.com/apollostack/apollo-client/issues/707
// Basically: is there a query in flight right now (modolo the next tick)?
var loading = (this.options.fetchPolicy === 'network-only' && queryLoading) ||
(partial && this.options.fetchPolicy !== 'cache-only');
// if there is nothing in the query store, it means this query hasn't fired yet or it has been cleaned up. Therefore the
// network status is dependent on queryLoading.
var networkStatus;

@@ -126,2 +154,4 @@ if (queryStoreValue) {

};
// Returns the last result that observer.next was called with. This is not the same as
// currentResult! If you're not sure which you need, then you probably need currentResult.
ObservableQuery.prototype.getLastResult = function () {

@@ -139,12 +169,19 @@ return this.lastResult;

ObservableQuery.prototype.refetch = function (variables) {
if (this.options.fetchPolicy === 'cache-only') {
var fetchPolicy = this.options.fetchPolicy;
// early return if trying to read from cache during refetch
if (fetchPolicy === 'cache-only') {
return Promise.reject(new Error('cache-only fetchPolicy option should not be used together with query refetch.'));
}
if (!isEqual(this.variables, variables)) {
// update observable variables
this.variables = __assign({}, this.variables, variables);
}
if (!isEqual(this.options.variables, this.variables)) {
// Update the existing options with new variables
this.options.variables = __assign({}, this.options.variables, this.variables);
}
var combinedOptions = __assign({}, this.options, { fetchPolicy: 'network-only' });
// Override fetchPolicy for this call only
// only network-only and no-cache are safe to use
var isNetworkFetchPolicy = fetchPolicy === 'network-only' || fetchPolicy === 'no-cache';
var combinedOptions = __assign({}, this.options, { fetchPolicy: isNetworkFetchPolicy ? fetchPolicy : 'network-only' });
return this.queryManager

@@ -156,2 +193,3 @@ .fetchQuery(this.queryId, combinedOptions, FetchType.refetch)

var _this = this;
// early return if no update Query
if (!fetchMoreOptions.updateQuery) {

@@ -165,5 +203,7 @@ throw new Error('updateQuery option is required. This function defines how to update the query data with the new results.');

if (fetchMoreOptions.query) {
// fetch a new query
combinedOptions = fetchMoreOptions;
}
else {
// fetch the same query with a possibly new variables
combinedOptions = __assign({}, _this.options, fetchMoreOptions, { variables: __assign({}, _this.variables, fetchMoreOptions.variables) });

@@ -185,2 +225,5 @@ }

};
// XXX the subscription variables are separate from the query variables.
// if you want to update subscription variables, right now you have to do that separately,
// and you can only do it by stopping the subscription and then subscribing again with new variables.
ObservableQuery.prototype.subscribeToMore = function (options) {

@@ -222,2 +265,4 @@ var _this = this;

};
// Note: if the query is not active (there are no subscribers), the promise
// will return null immediately.
ObservableQuery.prototype.setOptions = function (opts) {

@@ -232,2 +277,3 @@ var oldOptions = this.options;

}
// If fetchPolicy went from cache-only to something else, or from something else to network-only
var tryFetch = (oldOptions.fetchPolicy !== 'network-only' &&

@@ -242,8 +288,32 @@ opts.fetchPolicy === 'network-only') ||

};
/**
* Update the variables of this observable query, and fetch the new results
* if they've changed. If you want to force new results, use `refetch`.
*
* Note: if the variables have not changed, the promise will return the old
* results immediately, and the `next` callback will *not* fire.
*
* Note: if the query is not active (there are no subscribers), the promise
* will return null immediately.
*
* @param variables: The new set of variables. If there are missing variables,
* the previous values of those variables will be used.
*
* @param tryFetch: Try and fetch new results even if the variables haven't
* changed (we may still just hit the store, but if there's nothing in there
* this will refetch)
*
* @param fetchResults: Option to ignore fetching results when updating variables
*
*/
ObservableQuery.prototype.setVariables = function (variables, tryFetch, fetchResults) {
if (tryFetch === void 0) { tryFetch = false; }
if (fetchResults === void 0) { fetchResults = true; }
// since setVariables restarts the subscription, we reset the tornDown status
this.isTornDown = false;
var newVariables = __assign({}, this.variables, variables);
var newVariables = variables;
if (isEqual(newVariables, this.variables) && !tryFetch) {
// If we have no observers, then we don't actually want to make a network
// request. As soon as someone observes the query, the request will kick
// off. For now, we just store any changes. (See #1077)
if (this.observers.length === 0 || !fetchResults) {

@@ -258,5 +328,7 @@ return new Promise(function (resolve) { return resolve(); });

this.options.variables = newVariables;
// See comment above
if (this.observers.length === 0) {
return new Promise(function (resolve) { return resolve(); });
}
// Use the same options as before, but with new variables
return this.queryManager

@@ -299,2 +371,4 @@ .fetchQuery(this.queryId, __assign({}, this.options, { variables: this.variables }))

var _this = this;
// Zen Observable has its own error function, in order to log correctly
// we need to declare a custom error if nothing is passed
if (observer._subscription &&

@@ -308,2 +382,3 @@ observer._subscription._observer &&

this.observers.push(observer);
// Deliver initial result
if (observer.next && this.lastResult)

@@ -313,2 +388,3 @@ observer.next(this.lastResult);

observer.error(this.lastError);
// setup the query if it hasn't been done before
if (this.observers.length === 1)

@@ -354,2 +430,3 @@ this.setUpQuery();

}
// stop all active GraphQL subscriptions
this.subscriptionHandles.forEach(function (sub) { return sub.unsubscribe(); });

@@ -356,0 +433,0 @@ this.subscriptionHandles = [];

@@ -21,2 +21,3 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {

import { FetchType } from './types';
import { graphQLResultHasError } from 'apollo-utilities';
var defaultQueryInfo = {

@@ -36,5 +37,14 @@ listeners: [],

this.queryStore = new QueryStore();
// let's not start at zero to avoid pain with bad checks
this.idCounter = 1;
// XXX merge with ObservableQuery but that needs to be expanded to support mutations and
// subscriptions as well
this.queries = new Map();
// A map going from a requestId to a promise that has not yet been resolved. We use this to keep
// track of queries that are inflight and reject them in case some
// destabalizing action occurs (e.g. reset of the Apollo store).
this.fetchQueryPromises = new Map();
// A map going from the name of a query to an observer issued for it by watchQuery. This is
// generally used to refetches for refetchQueries and to update mutation results through
// updateQueries.
this.queryIdsByName = {};

@@ -63,2 +73,3 @@ this.link = link;

this.setQuery(mutationId, function () { return ({ document: mutation }); });
// Create a map of update queries by id to the query instead of by name.
var generateUpdateQueriesInfo = function () {

@@ -94,3 +105,3 @@ var ret = {};

next: function (result) {
if (result.errors && errorPolicy === 'none') {
if (graphQLResultHasError(result) && errorPolicy === 'none') {
error = new ApolloError({

@@ -139,2 +150,4 @@ graphQLErrors: result.errors,

}
// allow for conditional refetches
// XXX do we want to make this the only API one day?
if (typeof refetchQueries === 'function')

@@ -154,3 +167,5 @@ refetchQueries = refetchQueries(storeResult);

_this.setQuery(mutationId, function () { return ({ document: undefined }); });
if (errorPolicy === 'ignore' && storeResult && storeResult.errors) {
if (errorPolicy === 'ignore' &&
storeResult &&
graphQLResultHasError(storeResult)) {
delete storeResult.errors;

@@ -163,3 +178,7 @@ }

};
QueryManager.prototype.fetchQuery = function (queryId, options, fetchType, fetchMoreForQueryId) {
QueryManager.prototype.fetchQuery = function (queryId, options, fetchType,
// This allows us to track if this is a query spawned by a `fetchMore`
// call for another query. We need this data to compute the `fetchMore`
// network status for the query this is fetching for.
fetchMoreForQueryId) {
var _this = this;

@@ -171,2 +190,5 @@ var _a = options.variables, variables = _a === void 0 ? {} : _a, _b = options.metadata, metadata = _b === void 0 ? null : _b, _c = options.fetchPolicy, fetchPolicy = _c === void 0 ? 'cache-first' : _c;

var needToFetch = fetchPolicy === 'network-only' || fetchPolicy === 'no-cache';
// If this is not a force fetch, we want to diff the query against the
// store before we fetch it from the network interface.
// TODO we hit the cache even if the policy is network-first. This could be unnecessary if the network is up.
if (fetchType !== FetchType.refetch &&

@@ -181,2 +203,3 @@ fetchPolicy !== 'network-only' &&

}), complete = _d.complete, result = _d.result;
// If we're in here, only fetch if we have missing fields
needToFetch = !complete || fetchPolicy === 'cache-and-network';

@@ -186,6 +209,9 @@ storeResult = result;

var shouldFetch = needToFetch && fetchPolicy !== 'cache-only' && fetchPolicy !== 'standby';
// we need to check to see if this is an operation that uses the @live directive
if (hasDirectives(['live'], query))
shouldFetch = true;
var requestId = this.generateRequestId();
// set up a watcher to listen to cache updates
var cancel = this.updateQueryWatch(queryId, query, options);
// Initialize query in store with unique requestId
this.setQuery(queryId, function () { return ({

@@ -210,2 +236,4 @@ document: query,

this.broadcastQueries();
// If there is no part of the query we need to fetch from the server (or,
// fetchPolicy is cache-only), we just write the store result as the final result.
var shouldDispatchClientResult = !shouldFetch || fetchPolicy === 'cache-and-network';

@@ -225,2 +253,4 @@ if (shouldDispatchClientResult) {

}).catch(function (error) {
// This is for the benefit of `refetch` promises, which currently don't get their errors
// through the store like watchQuery observers do
if (isApolloError(error)) {

@@ -240,2 +270,4 @@ throw error;

});
// we don't return the promise for cache-and-network since it is already
// returned below from the cache
if (fetchPolicy !== 'cache-and-network') {

@@ -245,7 +277,13 @@ return networkResult;

else {
// however we need to catch the error so it isn't unhandled in case of
// network error
networkResult.catch(function () { });
}
}
// If we have no query to send to the server, we should return the result
// found within the store.
return Promise.resolve({ data: storeResult });
};
// Returns a query listener that will update the given observer based on the
// results (or lack thereof) for a particular query.
QueryManager.prototype.queryListenerForObserver = function (queryId, options, observer) {

@@ -255,3 +293,6 @@ var _this = this;

return function (queryStoreValue, newData) {
// we're going to take a look at the data, so the query is no longer invalidated
_this.invalidate(false, queryId);
// The query store value can be undefined in the event of a store
// reset.
if (!queryStoreValue)

@@ -263,2 +304,3 @@ return;

: options.fetchPolicy;
// don't watch the store for queries on standby
if (fetchPolicy === 'standby')

@@ -276,2 +318,10 @@ return;

fetchPolicy === 'cache-and-network';
// if this caused by a cache broadcast but the query is still in flight
// don't notify the observer
// if (
// isCacheBroadcast &&
// isNetworkRequestInFlight(queryStoreValue.networkStatus)
// ) {
// shouldNotifyIfLoading = false;
// }
var networkStatusChanged = Boolean(lastResult &&

@@ -286,2 +336,4 @@ queryStoreValue.networkStatus !== lastResult.networkStatus);

shouldNotifyIfLoading) {
// If we have either a GraphQL error or a network error, we create
// an error and tell the observer about it.
if (((!errorPolicy || errorPolicy === 'none') &&

@@ -301,2 +353,3 @@ queryStoreValue.graphQLErrors &&

catch (e) {
// Throw error outside this control flow to avoid breaking Apollo's state
setTimeout(function () {

@@ -308,2 +361,3 @@ throw e;

else {
// Throw error outside this control flow to avoid breaking Apollo's state
setTimeout(function () {

@@ -313,2 +367,3 @@ throw apolloError_1;

if (!isProduction()) {
/* tslint:disable-next-line */
console.info('An unhandled error was thrown because no error handler is registered ' +

@@ -325,2 +380,3 @@ 'for the query ' +

if (newData) {
// clear out the latest new data, since we're now using it
_this.setQuery(queryId, function () { return ({ newData: null }); });

@@ -348,2 +404,5 @@ data = newData.result;

var resultFromStore = void 0;
// If there is some data missing and the user has told us that they
// do not tolerate partial data then we want to return the previous
// result and mark it as stale.
if (isMissing && fetchPolicy !== 'cache-only') {

@@ -365,2 +424,3 @@ resultFromStore = {

}
// if the query wants updates on errors we need to add it to the result
if (errorPolicy === 'all' &&

@@ -376,2 +436,5 @@ queryStoreValue.graphQLErrors &&

lastResult.stale === resultFromStore.stale &&
// We can do a strict equality check here because we include a `previousResult`
// with `readQueryFromStore`. So if the results are the same they will be
// referentially equal.
lastResult.data === resultFromStore.data);

@@ -383,2 +446,3 @@ if (isDifferentResult || previouslyHadError) {

catch (e) {
// Throw error outside this control flow to avoid breaking Apollo's state
setTimeout(function () {

@@ -401,2 +465,8 @@ throw e;

};
// The shouldSubscribe option is a temporary fix that tells us whether watchQuery was called
// directly (i.e. through ApolloClient) or through the query method within QueryManager.
// Currently, the query method uses watchQuery in order to handle non-network errors correctly
// but we don't want to keep track observables issued for the query method since those aren't
// supposed to be refetched in the event of a store reset. Once we unify error handling for
// network errors and non-network errors, the shouldSubscribe option will go away.
QueryManager.prototype.watchQuery = function (options, shouldSubscribe) {

@@ -407,3 +477,5 @@ if (shouldSubscribe === void 0) { shouldSubscribe = true; }

}
// get errors synchronously
var queryDefinition = getQueryDefinition(options.query);
// assign variable default values if supplied
if (queryDefinition.variableDefinitions &&

@@ -503,2 +575,3 @@ queryDefinition.variableDefinitions.length) {

};
// Adds a promise to this.fetchQueryPromises for a given request ID.
QueryManager.prototype.addFetchQueryPromise = function (requestId, promise, resolve, reject) {

@@ -511,10 +584,14 @@ this.fetchQueryPromises.set(requestId.toString(), {

};
// Removes the promise in this.fetchQueryPromises for a particular request ID.
QueryManager.prototype.removeFetchQueryPromise = function (requestId) {
this.fetchQueryPromises.delete(requestId.toString());
};
// Adds an ObservableQuery to this.observableQueries and to this.observableQueriesByName.
QueryManager.prototype.addObservableQuery = function (queryId, observableQuery) {
this.setQuery(queryId, function () { return ({ observableQuery: observableQuery }); });
// Insert the ObservableQuery into this.observableQueriesByName if the query has a name
var queryDef = getQueryDefinition(observableQuery.options.query);
if (queryDef.name && queryDef.name.value) {
var queryName = queryDef.name.value;
// XXX we may we want to warn the user about query name conflicts in the future
this.queryIdsByName[queryName] = this.queryIdsByName[queryName] || [];

@@ -540,2 +617,8 @@ this.queryIdsByName[queryName].push(observableQuery.queryId);

QueryManager.prototype.clearStore = function () {
// Before we have sent the reset action to the store,
// we can no longer rely on the results returned by in-flight
// requests since these may depend on values that previously existed
// in the data portion of the store. So, we cancel the promises and observers
// that we have issued so far and not yet resolved (in the case of
// queries).
this.fetchQueryPromises.forEach(function (_a) {

@@ -553,2 +636,3 @@ var reject = _a.reject;

this.mutationStore.reset();
// begin removing data from the store
var reset = this.dataStore.reset();

@@ -559,2 +643,8 @@ return reset;

var _this = this;
// Similarly, we have to have to refetch each of the queries currently being
// observed. We refetch instead of error'ing on these since the assumption is that
// resetting the store doesn't eliminate the need for the queries currently being
// watched. If there is an existing query in flight when the store is reset,
// the promise for it will be rejected and its results will not be written to the
// store.
return this.clearStore().then(function () {

@@ -603,2 +693,3 @@ return _this.reFetchObservableQueries();

observers.push(observer);
// If this is the first observer, actually initiate the network subscription
if (observers.length === 1) {

@@ -609,3 +700,5 @@ var handler = {

_this.broadcastQueries();
// It's slightly awkward that the data for subscriptions doesn't come from the store.
observers.forEach(function (obs) {
// XXX I'd prefer a different way to handle errors for subscriptions
if (obs.next)

@@ -622,2 +715,4 @@ obs.next(result);

};
// TODO: Should subscriptions also accept a `context` option to pass
// through to links?
var operation = _this.buildOperationForLink(transformedDoc, variables);

@@ -628,2 +723,3 @@ sub = execute(_this.link, operation).subscribe(handler);

observers = observers.filter(function (obs) { return obs !== observer; });
// If we removed the last observer, tear down the network subscription
if (observers.length === 0 && sub) {

@@ -641,2 +737,3 @@ sub.unsubscribe();

var subscriptions = this.getQuery(queryId).subscriptions;
// teardown all links
subscriptions.forEach(function (x) { return x.unsubscribe(); });

@@ -650,2 +747,3 @@ this.queries.delete(queryId);

var newData = this.getQuery(observableQuery.queryId).newData;
// XXX test this
if (newData) {

@@ -656,2 +754,3 @@ return maybeDeepFreeze({ data: newData.result, partial: false });

try {
// the query is brand new, so we read from the store to see if anything is there
var data = this.dataStore.getCache().read({

@@ -703,2 +802,5 @@ query: query,

};
// Takes a request id, query id, a query document and information associated with the query
// and send it to the network interface. Returns
// a promise for the result associated with that request.
QueryManager.prototype.fetchRequest = function (_a) {

@@ -708,3 +810,6 @@ var _this = this;

var variables = options.variables, context = options.context, _b = options.errorPolicy, errorPolicy = _b === void 0 ? 'none' : _b, fetchPolicy = options.fetchPolicy;
var operation = this.buildOperationForLink(document, variables, __assign({}, context, { forceFetch: !this.queryDeduplication }));
var operation = this.buildOperationForLink(document, variables, __assign({}, context, {
// TODO: Should this be included for all entry points via
// buildOperationForLink?
forceFetch: !this.queryDeduplication }));
var resultFromStore;

@@ -716,2 +821,3 @@ var errorsFromStore;

next: function (result) {
// default the lastRequestId to 1
var lastRequestId = _this.getQuery(queryId).lastRequestId;

@@ -728,2 +834,7 @@ if (requestId >= (lastRequestId || 1)) {

}
else {
_this.setQuery(queryId, function () { return ({
newData: { result: result.data, complete: true },
}); });
}
_this.queryStore.markQueryResult(queryId, result, fetchMoreForQueryId);

@@ -742,3 +853,5 @@ _this.invalidate(true, queryId, fetchMoreForQueryId);

}
if (fetchMoreForQueryId) {
if (fetchMoreForQueryId || fetchPolicy === 'no-cache') {
// We don't write fetchMore results to the store because this would overwrite
// the original result in case an @connection directive is used.
resultFromStore = result.data;

@@ -748,2 +861,3 @@ }

try {
// ensure result is combined with data already in store
resultFromStore = _this.dataStore.getCache().read({

@@ -754,2 +868,5 @@ variables: variables,

});
// this will throw an error if there are missing fields in
// the results which can happen with errors from the server.
// tslint:disable-next-line
}

@@ -795,5 +912,10 @@ catch (e) { }

};
// Refetches a query given that query's name. Refetches
// all ObservableQuery instances associated with the query name.
QueryManager.prototype.refetchQueryByName = function (queryName) {
var _this = this;
var refetchedQueries = this.queryIdsByName[queryName];
// early return if the query named does not exist (not yet fetched)
// this used to warn but it may be inteneded behavoir to try and refetch
// un called queries because they could be on different routes
if (refetchedQueries === undefined)

@@ -834,4 +956,7 @@ return;

operationName: getOperationName(document) || undefined,
context: __assign({}, extraContext, { cache: cache, getCacheKey: function (obj) {
context: __assign({}, extraContext, { cache: cache,
// getting an entry's cache key is useful for cacheResolvers & state-link
getCacheKey: function (obj) {
if (cache.config) {
// on the link, we just want the id string, not the full id value from toIdValue
return cache.config.dataIdFromObject(obj);

@@ -838,0 +963,0 @@ }

@@ -6,17 +6,69 @@ import { DocumentNode, ExecutionResult } from 'graphql';

import { PureQueryOptions } from './types';
/**
* fetchPolicy determines where the client may return a result from. The options are:
* - cache-first (default): return result from cache. Only fetch from network if cached result is not available.
* - cache-and-network: return result from cache first (if it exists), then return network result once it's available.
* - cache-only: return result from cache if available, fail otherwise.
* - no-cache: return result from network, fail if network call doesn't succeed, don't save to cache
* - network-only: return result from network, fail if network call doesn't succeed, save to cache
* - standby: only for queries that aren't actively watched, but should be available for refetch and updateQueries.
*/
export declare type FetchPolicy = 'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only' | 'no-cache' | 'standby';
/**
* errorPolicy determines the level of events for errors in the execution result. The options are:
* - none (default): any errors from the request are treated like runtime errors and the observable is stopped (XXX this is default to lower breaking changes going from AC 1.0 => 2.0)
* - ignore: errors from the request do not stop the observable, but also don't call `next`
* - all: errors are treated like data and will notify observables
*/
export declare type ErrorPolicy = 'none' | 'ignore' | 'all';
/**
* We can change these options to an ObservableQuery
*/
export interface ModifiableWatchQueryOptions {
/**
* A map going from variable name to variable value, where the variables are used
* within the GraphQL query.
*/
variables?: {
[key: string]: any;
};
/**
* The time interval (in milliseconds) on which this query should be
* refetched from the server.
*/
pollInterval?: number;
/**
* Specifies the {@link FetchPolicy} to be used for this query
*/
fetchPolicy?: FetchPolicy;
/**
* Specifies the {@link ErrorPolicy} to be used for this query
*/
errorPolicy?: ErrorPolicy;
/**
* Whether or not to fetch results
*/
fetchResults?: boolean;
/**
* Whether or not updates to the network status should trigger next on the observer of this query
*/
notifyOnNetworkStatusChange?: boolean;
}
/**
* The argument to a query
*/
export interface WatchQueryOptions extends ModifiableWatchQueryOptions {
/**
* A GraphQL document that consists of a single query to be sent down to the
* server.
*/
query: DocumentNode;
/**
* Arbitrary metadata stored in the store with this query. Designed for debugging,
* developer tools, etc.
*/
metadata?: any;
/**
* Context to be passed to link execution chain
*/
context?: any;

@@ -47,3 +99,11 @@ }

export interface SubscriptionOptions {
/**
* A GraphQL document, often created with `gql` from the `graphql-tag`
* package, that contains a single subscription inside of it.
*/
query: DocumentNode;
/**
* An object that maps from the name of a variable as used in the subscription
* GraphQL document to that variable's value.
*/
variables?: {

@@ -57,7 +117,52 @@ [key: string]: any;

}> {
/**
* An object that represents the result of this mutation that will be
* optimistically stored before the server has actually returned a result.
* This is most often used for optimistic UI, where we want to be able to see
* the result of a mutation immediately, and update the UI later if any errors
* appear.
*/
optimisticResponse?: Object | Function;
/**
* A {@link MutationQueryReducersMap}, which is map from query names to
* mutation query reducers. Briefly, this map defines how to incorporate the
* results of the mutation into the results of queries that are currently
* being watched by your application.
*/
updateQueries?: MutationQueryReducersMap<T>;
/**
* A list of query names which will be refetched once this mutation has
* returned. This is often used if you have a set of queries which may be
* affected by a mutation and will have to update. Rather than writing a
* mutation query reducer (i.e. `updateQueries`) for this, you can simply
* refetch the queries that will be affected and achieve a consistent store
* once these queries return.
*/
refetchQueries?: ((result: ExecutionResult) => RefetchQueryDescription) | RefetchQueryDescription;
/**
* A function which provides a {@link DataProxy} and the result of the
* mutation to allow the user to update the store based on the results of the
* mutation.
*
* This function will be called twice over the lifecycle of a mutation. Once
* at the very beginning if an `optimisticResponse` was provided. The writes
* created from the optimistic data will be rolled back before the second time
* this function is called which is when the mutation has succesfully
* resolved. At that point `update` will be called with the *actual* mutation
* result and those writes will not be rolled back.
*
* The reason a {@link DataProxy} is provided instead of the user calling the
* methods directly on {@link ApolloClient} is that all of the writes are
* batched together at the end of the update, and it allows for writes
* generated by optimistic data to be rolled back.
*/
update?: MutationUpdaterFn<T>;
/**
* Specifies the {@link ErrorPolicy} to be used for this operation
*/
errorPolicy?: ErrorPolicy;
/**
* An object that maps from the name of a variable as used in the mutation
* GraphQL document to that variable's value.
*/
variables?: any;

@@ -68,4 +173,14 @@ }

}> extends MutationBaseOptions<T> {
/**
* A GraphQL document, often created with `gql` from the `graphql-tag`
* package, that contains a single mutation inside of it.
*/
mutation: DocumentNode;
/**
* Context to be passed to link execution chain
*/
context?: any;
/**
* Specifies the {@link FetchPolicy} to be used for this query
*/
fetchPolicy?: FetchPolicy;

@@ -72,0 +187,0 @@ }

@@ -24,2 +24,5 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {

if (previousQuery && previousQuery.queryString !== query.queryString) {
// XXX we're throwing an error here to catch bugs where a query gets overwritten by a new one.
// we should implement a separate action for refetching so that QUERY_INIT may never overwrite
// an existing query (see also: https://github.com/apollostack/apollo-client/issues/732)
throw new Error('Internal Error: may not update existing query string in store');

@@ -37,2 +40,3 @@ }

}
// TODO break this out into a separate function
var networkStatus;

@@ -47,2 +51,3 @@ if (isSetVariables) {

networkStatus = NetworkStatus.refetch;
// TODO: can we determine setVariables here if it's a refetch and the variables have changed?
}

@@ -56,2 +61,5 @@ else {

}
// XXX right now if QUERY_INIT is fired twice, like in a refetch situation, we just overwrite
// the store. We probably want a refetch action instead, because I suspect that if you refetch
// before the initial fetch is done, you'll get an error.
this.store[query.queryId] = {

@@ -67,2 +75,9 @@ queryString: query.queryString,

};
// If the action had a `moreForQueryId` property then we need to set the
// network status on that query as well to `fetchMore`.
//
// We have a complement to this if statement in the query result and query
// error action branch, but importantly *not* in the client result branch.
// This is because the implementation of `fetchMore` *always* sets
// `fetchPolicy` to `network-only` so we would never have a client result.
if (typeof query.fetchMoreForQueryId === 'string') {

@@ -81,2 +96,5 @@ this.store[query.fetchMoreForQueryId].networkStatus =

this.store[queryId].networkStatus = NetworkStatus.ready;
// If we have a `fetchMoreForQueryId` then we need to update the network
// status for that query. See the branch for query initialization for more
// explanation about this process.
if (typeof fetchMoreForQueryId === 'string') {

@@ -91,4 +109,7 @@ this.store[fetchMoreForQueryId].networkStatus = NetworkStatus.ready;

this.store[queryId].networkStatus = NetworkStatus.error;
// If we have a `fetchMoreForQueryId` then we need to update the network
// status for that query. See the branch for query initialization for more
// explanation about this process.
if (typeof fetchMoreForQueryId === 'string') {
this.markQueryError(fetchMoreForQueryId, error, undefined);
this.markQueryResultClient(fetchMoreForQueryId, true);
}

@@ -110,2 +131,3 @@ };

var _this = this;
// keep only the queries with query ids that are associated with observables
this.store = Object.keys(this.store)

@@ -116,2 +138,3 @@ .filter(function (queryId) {

.reduce(function (res, key) {
// XXX set loading to true so listeners don't trigger unless they want results with partial data
res[key] = __assign({}, _this.store[key], { networkStatus: NetworkStatus.loading });

@@ -118,0 +141,0 @@ return res;

@@ -25,2 +25,4 @@ import { getOperationName, tryFunctionOrLogError, graphQLResultHasError, } from 'apollo-utilities';

DataStore.prototype.markSubscriptionResult = function (result, document, variables) {
// the subscription interface should handle not sending us results we no longer subscribe to.
// XXX I don't think we ever send in an object with errors, but we might in the future...
if (!graphQLResultHasError(result)) {

@@ -69,2 +71,3 @@ this.cache.write({

var _this = this;
// Incorporate the result from this mutation into the store
if (!graphQLResultHasError(mutation.result)) {

@@ -83,2 +86,3 @@ var cacheWrites_1 = [];

var _a = mutation.updateQueries[queryId], query = _a.query, updater = _a.updater;
// Read the current query result from the store.
var _b = _this.cache.diff({

@@ -93,2 +97,3 @@ query: query.document,

}
// Run our reducer using the current query result and the mutation result.
var nextQueryResult = tryFunctionOrLogError(function () {

@@ -101,2 +106,3 @@ return updater(currentQueryResult, {

});
// Write the modified result back into the store if we got a new result.
if (nextQueryResult) {

@@ -115,2 +121,5 @@ cacheWrites_1.push({

});
// If the mutation has some writes associated with it then we need to
// apply those writes to the store by running this reducer again with a
// write action.
var update_1 = mutation.update;

@@ -117,0 +126,0 @@ if (update_1) {

@@ -14,4 +14,9 @@ var __extends = (this && this.__extends) || (function () {

}
// Sets the error message on this error according to the
// the GraphQL and network errors that are present.
// If the error message has already been set through the
// constructor or otherwise, this function is a nop.
var generateErrorMessage = function (err) {
var message = '';
// If we have GraphQL errors present, add that to the error message.
if (Array.isArray(err.graphQLErrors) && err.graphQLErrors.length !== 0) {

@@ -28,2 +33,3 @@ err.graphQLErrors.forEach(function (graphQLError) {

}
// strip newline from the end of the message
message = message.replace(/\n$/, '');

@@ -34,2 +40,5 @@ return message;

__extends(ApolloError, _super);
// Constructs an instance of ApolloError given a GraphQLError
// or a network error. Note that one of these has to be a valid
// value or the constructed error will be meaningless.
function ApolloError(_a) {

@@ -47,2 +56,3 @@ var graphQLErrors = _a.graphQLErrors, networkError = _a.networkError, errorMessage = _a.errorMessage, extraInfo = _a.extraInfo;

_this.extraInfo = extraInfo;
Object.setPrototypeOf(_this, ApolloError.prototype);
return _this;

@@ -49,0 +59,0 @@ }

@@ -7,4 +7,5 @@ export { print as printAST } from 'graphql/language/printer';

import ApolloClient from './ApolloClient';
// export the client as both default and named
export { ApolloClient };
export default ApolloClient;
//# sourceMappingURL=index.js.map

22

package.json
{
"name": "apollo-client",
"version": "2.2.7",
"version": "2.2.8",
"description": "A simple yet functional GraphQL client.",

@@ -27,6 +27,6 @@ "main": "bundle.umd.js",

"@types/zen-observable": "^0.5.3",
"apollo-cache": "^1.1.6",
"apollo-cache": "^1.1.7",
"apollo-link": "^1.0.0",
"apollo-link-dedup": "^1.0.0",
"apollo-utilities": "^1.0.10",
"apollo-utilities": "^1.0.11",
"symbol-observable": "^1.0.2",

@@ -40,8 +40,8 @@ "zen-observable": "^0.7.0"

"@types/benchmark": "1.0.31",
"@types/graphql": "0.12.4",
"@types/graphql": "0.12.5",
"@types/isomorphic-fetch": "0.0.34",
"@types/jest": "21.1.10",
"@types/lodash": "4.14.102",
"@types/node": "8.5.9",
"apollo-cache-inmemory": "^1.1.11",
"@types/lodash": "4.14.105",
"@types/node": "8.9.5",
"apollo-cache-inmemory": "^1.1.12",
"benchmark": "2.1.4",

@@ -51,5 +51,5 @@ "browserify": "15.2.0",

"danger": "1.1.0",
"flow-bin": "0.67.1",
"flow-bin": "0.68.0",
"github": "12.1.0",
"graphql": "0.13.1",
"graphql": "0.13.2",
"graphql-tag": "2.8.0",

@@ -61,7 +61,7 @@ "isomorphic-fetch": "2.2.1",

"rollup": "0.56.4",
"rxjs": "5.5.6",
"rxjs": "5.5.7",
"ts-jest": "20.0.14",
"tslint": "5.9.1",
"typescript": "2.4.2",
"uglify-js": "3.3.13",
"uglify-js": "3.3.16",
"webpack": "3.10.0",

@@ -68,0 +68,0 @@ "webpack-bundle-analyzer": "2.11.1"

@@ -1,4 +0,3 @@

# [Apollo client](https://www.apollographql.com/client/) [![npm version](https://badge.fury.io/js/apollo-client.svg)](https://badge.fury.io/js/apollo-client) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)
# [Apollo client](https://www.apollographql.com/client/) [![npm version](https://badge.fury.io/js/apollo-client.svg)](https://badge.fury.io/js/apollo-client) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack) [![Open Source Helpers](https://www.codetriage.com/apollographql/apollo-client/badges/users.svg)](https://www.codetriage.com/apollographql/apollo-client)
Apollo Client is a fully-featured caching GraphQL client with integrations for React, Angular, and more. It allows you to easily build UI components that fetch data via GraphQL. To get the most value out of `apollo-client`, you should use it with one of its view layer integrations.

@@ -5,0 +4,0 @@

@@ -0,1 +1,7 @@

// The QueryScheduler is supposed to be a mechanism that schedules polling queries such that
// they are clustered into the time slots of the QueryBatcher and are batched together. It
// also makes sure that for a given polling query, if one instance of the query is inflight,
// another instance will not be fired until the query returns or times out. We do this because
// another query fires while one is already in flight, the data will stay in the "loading" state
// even after the first query has returned.
var __assign = (this && this.__assign) || Object.assign || function(t) {

@@ -15,5 +21,11 @@ for (var s, i = 1, n = arguments.length; i < n; i++) {

var queryManager = _a.queryManager, ssrMode = _a.ssrMode;
// Map going from queryIds to query options that are in flight.
this.inFlightQueries = {};
// Map going from query ids to the query options associated with those queries. Contains all of
// the queries, both in flight and not in flight.
this.registeredQueries = {};
// Map going from polling interval with to the query ids that fire on that interval.
// These query ids are associated with a set of options in the this.registeredQueries.
this.intervalQueries = {};
// Map going from polling interval widths to polling timers.
this.pollingTimers = {};

@@ -47,2 +59,3 @@ this.ssrMode = false;

}
// Do not poll in SSR mode
if (this.ssrMode)

@@ -58,7 +71,22 @@ return queryId;

QueryScheduler.prototype.stopPollingQuery = function (queryId) {
// Remove the query options from one of the registered queries.
// The polling function will then take care of not firing it anymore.
delete this.registeredQueries[queryId];
};
// Fires the all of the queries on a particular interval. Called on a setInterval.
QueryScheduler.prototype.fetchQueriesOnInterval = function (interval) {
var _this = this;
// XXX this "filter" here is nasty, because it does two things at the same time.
// 1. remove queries that have stopped polling
// 2. call fetchQueries for queries that are polling and not in flight.
// TODO: refactor this to make it cleaner
this.intervalQueries[interval] = this.intervalQueries[interval].filter(function (queryId) {
// If queryOptions can't be found from registeredQueries or if it has a
// different interval, it means that this queryId is no longer registered
// and should be removed from the list of queries firing on this interval.
//
// We don't remove queries from intervalQueries immediately in
// stopPollingQuery so that we can keep the timer consistent when queries
// are removed and replaced, and to avoid quadratic behavior when stopping
// many queries.
if (!(_this.registeredQueries.hasOwnProperty(queryId) &&

@@ -68,2 +96,4 @@ _this.registeredQueries[queryId].pollInterval === interval)) {

}
// Don't fire this instance of the polling query is one of the instances is already in
// flight.
if (_this.checkInFlight(queryId)) {

@@ -75,2 +105,3 @@ return true;

pollingOptions.fetchPolicy = 'network-only';
// don't let unhandled rejections happen
_this.fetchQuery(queryId, pollingOptions, FetchType.poll).catch(function () { });

@@ -84,2 +115,5 @@ return true;

};
// Adds a query on a particular interval to this.intervalQueries and then fires
// that query with all the other queries executing on that interval. Note that the query id
// and query options must have been added to this.registeredQueries before this function is called.
QueryScheduler.prototype.addQueryOnInterval = function (queryId, queryOptions) {

@@ -91,2 +125,4 @@ var _this = this;

}
// If there are other queries on this interval, this query will just fire with those
// and we don't need to create a new timer.
if (this.intervalQueries.hasOwnProperty(interval.toString()) &&

@@ -98,2 +134,3 @@ this.intervalQueries[interval].length > 0) {

this.intervalQueries[interval] = [queryId];
// set up the timer for the function that will handle this interval
this.pollingTimers[interval] = setInterval(function () {

@@ -104,2 +141,3 @@ _this.fetchQueriesOnInterval(interval);

};
// Used only for unit testing.
QueryScheduler.prototype.registerPollingQuery = function (queryOptions) {

@@ -106,0 +144,0 @@ if (!queryOptions.pollInterval) {

@@ -11,4 +11,7 @@ var __extends = (this && this.__extends) || (function () {

})();
// This simplified polyfill attempts to follow the ECMAScript Observable proposal.
// See https://github.com/zenparsing/es-observable
import { Observable as LinkObservable } from 'apollo-link';
import $$observable from 'symbol-observable';
// rxjs interopt
var Observable = (function (_super) {

@@ -15,0 +18,0 @@ __extends(Observable, _super);

@@ -1,1 +0,1 @@

export declare const version = "2.2.7";
export declare const version = "2.2.8";

@@ -1,1 +0,1 @@

exports.version = "2.2.7"
exports.version = "2.2.8"

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc