@apollo/client
Version:
A fully-featured caching GraphQL client.
316 lines • 12.3 kB
JavaScript
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