UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

198 lines (196 loc) 7.86 kB
"use strict";; const { __DEV__ } = require("@apollo/client/utilities/environment"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ApolloCache = void 0; const caches_1 = require("@wry/caches"); const optimism_1 = require("optimism"); const rxjs_1 = require("rxjs"); const utilities_1 = require("@apollo/client/utilities"); const environment_1 = require("@apollo/client/utilities/environment"); const internal_1 = require("@apollo/client/utilities/internal"); const invariant_1 = require("@apollo/client/utilities/invariant"); class ApolloCache { assumeImmutableResults = false; // Function used to lookup a fragment when a fragment definition is not part // of the GraphQL document. This is useful for caches, such as InMemoryCache, // that register fragments ahead of time so they can be referenced by name. lookupFragment(fragmentName) { return null; } // Transactional API // The batch method is intended to replace/subsume both performTransaction // and recordOptimisticTransaction, but performTransaction came first, so we // provide a default batch implementation that's just another way of calling // performTransaction. Subclasses of ApolloCache (such as InMemoryCache) can // override the batch method to do more interesting things with its options. batch(options) { const optimisticId = typeof options.optimistic === "string" ? options.optimistic : options.optimistic === false ? null : void 0; let updateResult; this.performTransaction(() => (updateResult = options.update(this)), optimisticId); return updateResult; } recordOptimisticTransaction(transaction, optimisticId) { this.performTransaction(transaction, optimisticId); } // Optional API // Called once per input document, allowing the cache to make static changes // to the query, such as adding __typename fields. transformDocument(document) { return document; } // Called before each ApolloLink request, allowing the cache to make dynamic // changes to the query, such as filling in missing fragment definitions. transformForLink(document) { return document; } identify(object) { return; } gc() { return []; } modify(options) { return false; } readQuery(options, optimistic = !!options.optimistic) { return this.read({ ...options, rootId: options.id || "ROOT_QUERY", optimistic, }); } /** * Watches the cache store of the fragment according to the options specified * and returns an `Observable`. We can subscribe to this * `Observable` and receive updated results through an * observer when the cache store changes. * * 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`. * * @since 3.10.0 * @param options - An object of type `WatchFragmentOptions` that allows * the cache to identify the fragment and optionally specify whether to react * to optimistic updates. */ watchFragment(options) { const { fragment, fragmentName, from, optimistic = true, ...otherOptions } = options; const query = this.getFragmentDoc(fragment, fragmentName); // While our TypeScript types do not allow for `undefined` as a valid // `from`, its possible `useFragment` gives us an `undefined` since it // calls` cache.identify` and provides that value to `from`. We are // adding this fix here however to ensure those using plain JavaScript // and using `cache.identify` themselves will avoid seeing the obscure // warning. const id = typeof from === "undefined" || typeof from === "string" ? from : this.identify(from); if (environment_1.__DEV__) { const actualFragmentName = fragmentName || (0, internal_1.getFragmentDefinition)(fragment).name.value; if (!id) { __DEV__ && invariant_1.invariant.warn(110, actualFragmentName); } } const diffOptions = { ...otherOptions, returnPartialData: true, id, query, optimistic, }; let latestDiff; return new rxjs_1.Observable((observer) => { return this.watch({ ...diffOptions, immediate: true, callback: (diff) => { let data = diff.result; // TODO: Remove this once `watchFragment` supports `null` as valid // value emitted if (data === null) { data = {}; } if ( // Always ensure we deliver the first result latestDiff && (0, internal_1.equalByQuery)(query, { data: latestDiff.result }, { data }, options.variables)) { return; } const result = { data, dataState: diff.complete ? "complete" : "partial", complete: !!diff.complete, }; if (diff.missing) { result.missing = diff.missing.missing; } latestDiff = { ...diff, result: data }; observer.next(result); }, }); }); } // Make sure we compute the same (===) fragment query document every // time we receive the same fragment in readFragment. getFragmentDoc = (0, optimism_1.wrap)(internal_1.getFragmentQueryDocument, { max: utilities_1.cacheSizes["cache.fragmentQueryDocuments"] || 1000 /* defaultCacheSizes["cache.fragmentQueryDocuments"] */, cache: caches_1.WeakCache, }); readFragment(options, optimistic = !!options.optimistic) { return this.read({ ...options, query: this.getFragmentDoc(options.fragment, options.fragmentName), rootId: options.id, optimistic, }); } writeQuery({ id, data, ...options }) { return this.write(Object.assign(options, { dataId: id || "ROOT_QUERY", result: data, })); } writeFragment({ id, data, fragment, fragmentName, ...options }) { return this.write(Object.assign(options, { query: this.getFragmentDoc(fragment, fragmentName), dataId: id, result: data, })); } updateQuery(options, update) { return this.batch({ update(cache) { const value = cache.readQuery(options); const data = update(value); if (data === void 0 || data === null) return value; cache.writeQuery({ ...options, data }); return data; }, }); } updateFragment(options, update) { return this.batch({ update(cache) { const value = cache.readFragment(options); const data = update(value); if (data === void 0 || data === null) return value; cache.writeFragment({ ...options, data }); return data; }, }); } } exports.ApolloCache = ApolloCache; if (environment_1.__DEV__) { ApolloCache.prototype.getMemoryInternals = internal_1.getApolloCacheMemoryInternals; } //# sourceMappingURL=cache.cjs.map