@wora/relay-store
Version:
@wora Relay Store
178 lines • 9.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var relay_runtime_1 = require("relay-runtime");
var cache_persist_1 = require("@wora/cache-persist");
var DataChecker = tslib_1.__importStar(require("relay-runtime/lib/store/DataChecker"));
var ActorIdentifier_1 = require("relay-runtime/lib/multi-actor-environment/ActorIdentifier");
var INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE = 'INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE';
var hasOwn = Object.prototype.hasOwnProperty;
var Store = (function (_super) {
tslib_1.__extends(Store, _super);
function Store(recordSource, persistOptions, options) {
if (persistOptions === void 0) { persistOptions = {}; }
if (options === void 0) { options = {}; }
var _this = this;
var persistOptionsStore = tslib_1.__assign({ prefix: 'relay-store', serialize: true }, persistOptions);
if (!hasOwn.call(options, 'queryCacheExpirationTime')) {
options.queryCacheExpirationTime = 10 * 60 * 1000;
}
if (!hasOwn.call(options, 'gcReleaseBufferSize')) {
options.gcReleaseBufferSize = 0;
}
_this = _super.call(this, recordSource, options) || this;
_this.checkGC = function () { return _this.isRehydrated(); };
_this._cache = new cache_persist_1.Cache(persistOptionsStore);
_this._cache.values = function () {
return Object.values(_this._cache.getState());
};
_this._cache.entries = function () {
return Object.entries(_this._cache.getState());
};
_this._roots = _this._cache;
return _this;
}
Store.prototype.setCheckGC = function (checkGC) {
if (checkGC === void 0) { checkGC = function () { return true; }; }
this.checkGC = checkGC;
};
Store.prototype.purge = function () {
var _this = this;
var updateRecords = this.__getUpdatedRecordIDs();
Object.keys(this.getSource().toJSON()).forEach(function (key) {
updateRecords.add(key);
});
this._cache.purge();
return Promise.all([this._cache.flush(), this._recordSource.purge()]).then(function (result) {
_this.notify();
return result;
});
};
Store.prototype.hydrate = function () {
return Promise.all([this._cache.restore(), this._recordSource.restore()]);
};
Store.prototype.isRehydrated = function () {
return this._cache.isRehydrated() && (!this._recordSource.isRehydrated || this._recordSource.isRehydrated());
};
Store.prototype.getTTL = function (operation) {
return operation.request && operation.request.cacheConfig && operation.request.cacheConfig.ttl
? operation.request.cacheConfig.ttl
: this._queryCacheExpirationTime;
};
Store.prototype.retain = function (operation) {
var _this = this;
var ttl = this.getTTL(operation);
var id = operation.request.identifier;
var disposed = false;
var dispose = function () {
var root = _this._cache.get(id);
if (disposed || !root) {
return;
}
disposed = true;
root.refCount -= 1;
root.dispose = root.refCount === 0;
_this._cache.set(id, root);
var toSchedule = false;
_this._cache.getAllKeys().forEach(function (idCache) {
var _a = _this._cache.get(idCache), fetchTime = _a.fetchTime, retainTime = _a.retainTime, ttl = _a.ttl, dispose = _a.dispose;
var checkDate = fetchTime != null ? fetchTime : retainTime;
var expired = !_this.isCurrent(checkDate, ttl);
if (dispose && expired) {
toSchedule = true;
_this._cache.remove(idCache);
}
});
toSchedule && _this.scheduleGC();
};
var root = this._cache.get(id);
var refCount = !root || !root.refCount ? 1 : root.refCount + 1;
var newRoot = {
operation: operation,
dispose: false,
refCount: refCount,
epoch: !root ? null : root.epoch,
ttl: !root ? ttl : root.ttl,
retainTime: !root ? Date.now() : root.retainTime,
fetchTime: !root ? null : root.fetchTime,
};
this._cache.set(id, newRoot);
return { dispose: dispose };
};
Store.prototype.__gc = function () {
if (this._optimisticSource != null || !this.checkGC()) {
return;
}
var gcRun = this._collect();
while (!gcRun.next().done) { }
};
Store.prototype.scheduleGC = function () {
if (this._optimisticSource != null || !this.checkGC()) {
return;
}
_super.prototype.scheduleGC.call(this);
};
Store.prototype.isCurrent = function (fetchTime, ttl) {
return !!(ttl && fetchTime + ttl >= Date.now());
};
Store.prototype.check = function (operation, options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
var selector = operation.root;
var source = this._getMutableRecordSource();
var globalInvalidationEpoch = this._globalInvalidationEpoch;
var useExecTimeResolvers = (_c = (_a = operation.request.node.operation.use_exec_time_resolvers) !== null && _a !== void 0 ? _a : ((_b = operation.request.node.operation.exec_time_resolvers_enabled_provider) === null || _b === void 0 ? void 0 : _b.get()) === true) !== null && _c !== void 0 ? _c : false;
var rootEntry = this._cache.get(operation.request.identifier);
var operationLastWrittenAt = rootEntry != null ? rootEntry.epoch : null;
if (globalInvalidationEpoch != null) {
if (operationLastWrittenAt == null || operationLastWrittenAt <= globalInvalidationEpoch) {
return { status: 'stale' };
}
}
var getSourceForActor = (_e = (_d = options) === null || _d === void 0 ? void 0 : _d.getSourceForActor) !== null && _e !== void 0 ? _e : (function (actorIdentifier) {
ActorIdentifier_1.assertInternalActorIdentifier(actorIdentifier);
return source;
});
var getTargetForActor = (_g = (_f = options) === null || _f === void 0 ? void 0 : _f.getTargetForActor) !== null && _g !== void 0 ? _g : (function (actorIdentifier) {
ActorIdentifier_1.assertInternalActorIdentifier(actorIdentifier);
return source;
});
var handlers = (_h = options === null || options === void 0 ? void 0 : options.handlers) !== null && _h !== void 0 ? _h : [];
var operationAvailability = DataChecker.check(getSourceForActor, getTargetForActor, (_k = (_j = options) === null || _j === void 0 ? void 0 : _j.defaultActorIdentifier) !== null && _k !== void 0 ? _k : INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE, selector, handlers, this._operationLoader, this._getDataID, this._shouldProcessClientComponents, this.__log, useExecTimeResolvers);
return getAvailabilityStatus(operationAvailability, operationLastWrittenAt, rootEntry === null || rootEntry === void 0 ? void 0 : rootEntry.fetchTime, this.getTTL(operation), this.checkGC());
};
Store.prototype.notify = function (sourceOperation, invalidateStore) {
var updateRoot = sourceOperation && this._cache.has(sourceOperation.request.identifier);
var result = _super.prototype.notify.call(this, sourceOperation, invalidateStore);
if (sourceOperation != null) {
if (updateRoot) {
var id = sourceOperation.request.identifier;
var rootEntry = this._cache.get(id);
rootEntry.epoch = this._currentWriteEpoch;
rootEntry.fetchTime = Date.now();
this._cache.set(id, rootEntry);
}
}
return result;
};
return Store;
}(relay_runtime_1.Store));
exports.Store = Store;
function getAvailabilityStatus(operationAvailability, operationLastWrittenAt, operationFetchTime, queryCacheExpirationTime, staleForExpiration) {
var mostRecentlyInvalidatedAt = operationAvailability.mostRecentlyInvalidatedAt, status = operationAvailability.status;
if (typeof mostRecentlyInvalidatedAt === 'number') {
if (operationLastWrittenAt == null || mostRecentlyInvalidatedAt > operationLastWrittenAt) {
return { status: 'stale' };
}
}
if (status === 'missing') {
return { status: 'missing' };
}
if (operationFetchTime != null && queryCacheExpirationTime != null) {
var isStale = operationFetchTime <= Date.now() - queryCacheExpirationTime;
if (isStale && staleForExpiration) {
return { status: 'stale' };
}
}
return { status: 'available', fetchTime: operationFetchTime !== null && operationFetchTime !== void 0 ? operationFetchTime : null };
}
//# sourceMappingURL=Store.js.map