UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

316 lines 12.3 kB
import { __assign, __extends } from "tslib"; import { invariant } from "../../utilities/globals/index.js"; import "./fixPolyfills.js"; import { wrap } from 'optimism'; import { equal } from '@wry/equality'; import { ApolloCache } from "../core/cache.js"; import { MissingFieldError } from "../core/types/common.js"; import { addTypenameToDocument, isReference, } from "../../utilities/index.js"; import { StoreReader } from "./readFromStore.js"; import { StoreWriter } from "./writeToStore.js"; import { EntityStore, supportsResultCaching } from "./entityStore.js"; import { makeVar, forgetCache, recallCache } from "./reactiveVars.js"; import { Policies } from "./policies.js"; import { hasOwn, normalizeConfig, shouldCanonizeResults } from "./helpers.js"; import { canonicalStringify } from "./object-canon.js"; var InMemoryCache = (function (_super) { __extends(InMemoryCache, _super); function InMemoryCache(config) { if (config === void 0) { config = {}; } var _this = _super.call(this) || this; _this.watches = new Set(); _this.typenameDocumentCache = new Map(); _this.makeVar = makeVar; _this.txCount = 0; _this.config = normalizeConfig(config); _this.addTypename = !!_this.config.addTypename; _this.policies = new Policies({ cache: _this, dataIdFromObject: _this.config.dataIdFromObject, possibleTypes: _this.config.possibleTypes, typePolicies: _this.config.typePolicies, }); _this.init(); return _this; } InMemoryCache.prototype.init = function () { var rootStore = this.data = new EntityStore.Root({ policies: this.policies, resultCaching: this.config.resultCaching, }); this.optimisticData = rootStore.stump; this.resetResultCache(); }; InMemoryCache.prototype.resetResultCache = function (resetResultIdentities) { var _this = this; var previousReader = this.storeReader; var fragments = this.config.fragments; this.storeWriter = new StoreWriter(this, this.storeReader = new StoreReader({ cache: this, addTypename: this.addTypename, resultCacheMaxSize: this.config.resultCacheMaxSize, canonizeResults: shouldCanonizeResults(this.config), canon: resetResultIdentities ? void 0 : previousReader && previousReader.canon, fragments: fragments, }), fragments); this.maybeBroadcastWatch = wrap(function (c, options) { return _this.broadcastWatch(c, options); }, { max: this.config.resultCacheMaxSize, makeCacheKey: function (c) { var store = c.optimistic ? _this.optimisticData : _this.data; if (supportsResultCaching(store)) { var optimistic = c.optimistic, id = c.id, variables = c.variables; return store.makeCacheKey(c.query, c.callback, canonicalStringify({ optimistic: optimistic, id: id, variables: variables })); } } }); new Set([ this.data.group, this.optimisticData.group, ]).forEach(function (group) { return group.resetCaching(); }); }; InMemoryCache.prototype.restore = function (data) { this.init(); if (data) this.data.replace(data); return this; }; InMemoryCache.prototype.extract = function (optimistic) { if (optimistic === void 0) { optimistic = false; } return (optimistic ? this.optimisticData : this.data).extract(); }; InMemoryCache.prototype.read = function (options) { var _a = options.returnPartialData, returnPartialData = _a === void 0 ? false : _a; try { return this.storeReader.diffQueryAgainstStore(__assign(__assign({}, options), { store: options.optimistic ? this.optimisticData : this.data, config: this.config, returnPartialData: returnPartialData })).result || null; } catch (e) { if (e instanceof MissingFieldError) { return null; } throw e; } }; InMemoryCache.prototype.write = function (options) { try { ++this.txCount; return this.storeWriter.writeToStore(this.data, options); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); } } }; InMemoryCache.prototype.modify = function (options) { if (hasOwn.call(options, "id") && !options.id) { return false; } var store = options.optimistic ? this.optimisticData : this.data; try { ++this.txCount; return store.modify(options.id || "ROOT_QUERY", options.fields); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); } } }; InMemoryCache.prototype.diff = function (options) { return this.storeReader.diffQueryAgainstStore(__assign(__assign({}, options), { store: options.optimistic ? this.optimisticData : this.data, rootId: options.id || "ROOT_QUERY", config: this.config })); }; InMemoryCache.prototype.watch = function (watch) { var _this = this; if (!this.watches.size) { recallCache(this); } this.watches.add(watch); if (watch.immediate) { this.maybeBroadcastWatch(watch); } return function () { if (_this.watches.delete(watch) && !_this.watches.size) { forgetCache(_this); } _this.maybeBroadcastWatch.forget(watch); }; }; InMemoryCache.prototype.gc = function (options) { canonicalStringify.reset(); var ids = this.optimisticData.gc(); if (options && !this.txCount) { if (options.resetResultCache) { this.resetResultCache(options.resetResultIdentities); } else if (options.resetResultIdentities) { this.storeReader.resetCanon(); } } return ids; }; InMemoryCache.prototype.retain = function (rootId, optimistic) { return (optimistic ? this.optimisticData : this.data).retain(rootId); }; InMemoryCache.prototype.release = function (rootId, optimistic) { return (optimistic ? this.optimisticData : this.data).release(rootId); }; InMemoryCache.prototype.identify = function (object) { if (isReference(object)) return object.__ref; try { return this.policies.identify(object)[0]; } catch (e) { __DEV__ && invariant.warn(e); } }; InMemoryCache.prototype.evict = function (options) { if (!options.id) { if (hasOwn.call(options, "id")) { return false; } options = __assign(__assign({}, options), { id: "ROOT_QUERY" }); } try { ++this.txCount; return this.optimisticData.evict(options, this.data); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); } } }; InMemoryCache.prototype.reset = function (options) { var _this = this; this.init(); canonicalStringify.reset(); if (options && options.discardWatches) { this.watches.forEach(function (watch) { return _this.maybeBroadcastWatch.forget(watch); }); this.watches.clear(); forgetCache(this); } else { this.broadcastWatches(); } return Promise.resolve(); }; InMemoryCache.prototype.removeOptimistic = function (idToRemove) { var newOptimisticData = this.optimisticData.removeLayer(idToRemove); if (newOptimisticData !== this.optimisticData) { this.optimisticData = newOptimisticData; this.broadcastWatches(); } }; InMemoryCache.prototype.batch = function (options) { var _this = this; var update = options.update, _a = options.optimistic, optimistic = _a === void 0 ? true : _a, removeOptimistic = options.removeOptimistic, onWatchUpdated = options.onWatchUpdated; var updateResult; var perform = function (layer) { var _a = _this, data = _a.data, optimisticData = _a.optimisticData; ++_this.txCount; if (layer) { _this.data = _this.optimisticData = layer; } try { return updateResult = update(_this); } finally { --_this.txCount; _this.data = data; _this.optimisticData = optimisticData; } }; var alreadyDirty = new Set(); if (onWatchUpdated && !this.txCount) { this.broadcastWatches(__assign(__assign({}, options), { onWatchUpdated: function (watch) { alreadyDirty.add(watch); return false; } })); } if (typeof optimistic === 'string') { this.optimisticData = this.optimisticData.addLayer(optimistic, perform); } else if (optimistic === false) { perform(this.data); } else { perform(); } if (typeof removeOptimistic === "string") { this.optimisticData = this.optimisticData.removeLayer(removeOptimistic); } if (onWatchUpdated && alreadyDirty.size) { this.broadcastWatches(__assign(__assign({}, options), { onWatchUpdated: function (watch, diff) { var result = onWatchUpdated.call(this, watch, diff); if (result !== false) { alreadyDirty.delete(watch); } return result; } })); if (alreadyDirty.size) { alreadyDirty.forEach(function (watch) { return _this.maybeBroadcastWatch.dirty(watch); }); } } else { this.broadcastWatches(options); } return updateResult; }; InMemoryCache.prototype.performTransaction = function (update, optimisticId) { return this.batch({ update: update, optimistic: optimisticId || (optimisticId !== null), }); }; InMemoryCache.prototype.transformDocument = function (document) { if (this.addTypename) { var result = this.typenameDocumentCache.get(document); if (!result) { result = addTypenameToDocument(document); this.typenameDocumentCache.set(document, result); this.typenameDocumentCache.set(result, result); } return result; } return document; }; InMemoryCache.prototype.transformForLink = function (document) { var fragments = this.config.fragments; return fragments ? fragments.transform(document) : document; }; InMemoryCache.prototype.broadcastWatches = function (options) { var _this = this; if (!this.txCount) { this.watches.forEach(function (c) { return _this.maybeBroadcastWatch(c, options); }); } }; InMemoryCache.prototype.broadcastWatch = function (c, options) { var lastDiff = c.lastDiff; var diff = this.diff(c); if (options) { if (c.optimistic && typeof options.optimistic === "string") { diff.fromOptimisticTransaction = true; } if (options.onWatchUpdated && options.onWatchUpdated.call(this, c, diff, lastDiff) === false) { return; } } if (!lastDiff || !equal(lastDiff.result, diff.result)) { c.callback(c.lastDiff = diff, lastDiff); } }; return InMemoryCache; }(ApolloCache)); export { InMemoryCache }; //# sourceMappingURL=inMemoryCache.js.map