UNPKG

@data-client/core

Version:

Async State Management without the Management. REST, GraphQL, SSE, Websockets, Fetch

151 lines (149 loc) 19 kB
import { GC } from '../actionTypes.js'; export class GCPolicy { constructor({ // every 5 min intervalMS = 60 * 1000 * 5, expiryMultiplier = 2, expiresAt } = {}) { this.endpointCount = new Map(); this.entityCount = new Map(); this.endpointsQ = new Set(); this.entitiesQ = []; if (expiresAt) { this.expiresAt = expiresAt.bind(this); } this.options = { intervalMS, expiryMultiplier }; } init(controller) { this.controller = controller; this.intervalId = setInterval(() => { this.idleCallback(() => this.runSweep(), { timeout: 1000 }); }, this.options.intervalMS); } cleanup() { clearInterval(this.intervalId); } createCountRef({ key, paths = [] }) { // increment return () => { var _this$endpointCount$g; if (key) this.endpointCount.set(key, ((_this$endpointCount$g = this.endpointCount.get(key)) != null ? _this$endpointCount$g : 0) + 1); paths.forEach(path => { var _instanceCount$get; if (!this.entityCount.has(path.key)) { this.entityCount.set(path.key, new Map()); } const instanceCount = this.entityCount.get(path.key); instanceCount.set(path.pk, ((_instanceCount$get = instanceCount.get(path.pk)) != null ? _instanceCount$get : 0) + 1); }); // decrement return () => { if (key) { const currentCount = this.endpointCount.get(key); if (currentCount !== undefined) { if (currentCount <= 1) { this.endpointCount.delete(key); // queue for cleanup this.endpointsQ.add(key); } else { this.endpointCount.set(key, currentCount - 1); } } } paths.forEach(path => { if (!this.entityCount.has(path.key)) { return; } const instanceCount = this.entityCount.get(path.key); const entityCount = instanceCount.get(path.pk); if (entityCount !== undefined) { if (entityCount <= 1) { instanceCount.delete(path.pk); // queue for cleanup this.entitiesQ.push(path); } else { instanceCount.set(path.pk, entityCount - 1); } } }); }; }; } expiresAt({ fetchedAt, expiresAt }) { return Math.max((expiresAt - fetchedAt) * this.options.expiryMultiplier, 120000) + fetchedAt; } runSweep() { const state = this.controller.getState(); const entities = []; const endpoints = []; const now = Date.now(); const nextEndpointsQ = new Set(); for (const key of this.endpointsQ) { var _state$meta$key; if (!this.endpointCount.has(key) && this.expiresAt((_state$meta$key = state.meta[key]) != null ? _state$meta$key : { fetchedAt: 0, date: 0, expiresAt: 0 }) < now) { endpoints.push(key); } else { nextEndpointsQ.add(key); } } this.endpointsQ = nextEndpointsQ; const nextEntitiesQ = []; for (const path of this.entitiesQ) { var _this$entityCount$get, _state$entityMeta$pat, _state$entityMeta$pat2; if (!((_this$entityCount$get = this.entityCount.get(path.key)) != null && _this$entityCount$get.has(path.pk)) && this.expiresAt((_state$entityMeta$pat = (_state$entityMeta$pat2 = state.entityMeta[path.key]) == null ? void 0 : _state$entityMeta$pat2[path.pk]) != null ? _state$entityMeta$pat : { fetchedAt: 0, date: 0, expiresAt: 0 }) < now) { entities.push(path); } else { nextEntitiesQ.push(path); } } this.entitiesQ = nextEntitiesQ; if (entities.length || endpoints.length) { this.controller.dispatch({ type: GC, entities, endpoints }); } } /** Calls the callback when client is not 'busy' with high priority interaction tasks * * Override for platform-specific implementations */ idleCallback(callback, options) { if (typeof requestIdleCallback === 'function') { requestIdleCallback(callback, options); } else { callback(); } } } export class ImmortalGCPolicy { // eslint-disable-next-line @typescript-eslint/no-empty-function init() {} // eslint-disable-next-line @typescript-eslint/no-empty-function cleanup() {} createCountRef() { return () => () => undefined; } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJHQyIsIkdDUG9saWN5IiwiY29uc3RydWN0b3IiLCJpbnRlcnZhbE1TIiwiZXhwaXJ5TXVsdGlwbGllciIsImV4cGlyZXNBdCIsImVuZHBvaW50Q291bnQiLCJNYXAiLCJlbnRpdHlDb3VudCIsImVuZHBvaW50c1EiLCJTZXQiLCJlbnRpdGllc1EiLCJiaW5kIiwib3B0aW9ucyIsImluaXQiLCJjb250cm9sbGVyIiwiaW50ZXJ2YWxJZCIsInNldEludGVydmFsIiwiaWRsZUNhbGxiYWNrIiwicnVuU3dlZXAiLCJ0aW1lb3V0IiwiY2xlYW51cCIsImNsZWFySW50ZXJ2YWwiLCJjcmVhdGVDb3VudFJlZiIsImtleSIsInBhdGhzIiwiX3RoaXMkZW5kcG9pbnRDb3VudCRnIiwic2V0IiwiZ2V0IiwiZm9yRWFjaCIsInBhdGgiLCJfaW5zdGFuY2VDb3VudCRnZXQiLCJoYXMiLCJpbnN0YW5jZUNvdW50IiwicGsiLCJjdXJyZW50Q291bnQiLCJ1bmRlZmluZWQiLCJkZWxldGUiLCJhZGQiLCJwdXNoIiwiZmV0Y2hlZEF0IiwiTWF0aCIsIm1heCIsInN0YXRlIiwiZ2V0U3RhdGUiLCJlbnRpdGllcyIsImVuZHBvaW50cyIsIm5vdyIsIkRhdGUiLCJuZXh0RW5kcG9pbnRzUSIsIl9zdGF0ZSRtZXRhJGtleSIsIm1ldGEiLCJkYXRlIiwibmV4dEVudGl0aWVzUSIsIl90aGlzJGVudGl0eUNvdW50JGdldCIsIl9zdGF0ZSRlbnRpdHlNZXRhJHBhdCIsIl9zdGF0ZSRlbnRpdHlNZXRhJHBhdDIiLCJlbnRpdHlNZXRhIiwibGVuZ3RoIiwiZGlzcGF0Y2giLCJ0eXBlIiwiY2FsbGJhY2siLCJyZXF1ZXN0SWRsZUNhbGxiYWNrIiwiSW1tb3J0YWxHQ1BvbGljeSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdGF0ZS9HQ1BvbGljeS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEVudGl0eVBhdGggfSBmcm9tICdAZGF0YS1jbGllbnQvbm9ybWFsaXpyJztcblxuaW1wb3J0IHsgR0MgfSBmcm9tICcuLi9hY3Rpb25UeXBlcy5qcyc7XG5pbXBvcnQgQ29udHJvbGxlciBmcm9tICcuLi9jb250cm9sbGVyL0NvbnRyb2xsZXIuanMnO1xuXG5leHBvcnQgY2xhc3MgR0NQb2xpY3kgaW1wbGVtZW50cyBHQ0ludGVyZmFjZSB7XG4gIHByb3RlY3RlZCBlbmRwb2ludENvdW50ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJvdGVjdGVkIGVudGl0eUNvdW50ID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlcj4+KCk7XG4gIHByb3RlY3RlZCBlbmRwb2ludHNRID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHByb3RlY3RlZCBlbnRpdGllc1E6IEVudGl0eVBhdGhbXSA9IFtdO1xuXG4gIGRlY2xhcmUgcHJvdGVjdGVkIGludGVydmFsSWQ6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPjtcbiAgZGVjbGFyZSBwcm90ZWN0ZWQgY29udHJvbGxlcjogQ29udHJvbGxlcjtcbiAgZGVjbGFyZSBwcm90ZWN0ZWQgb3B0aW9uczogUmVxdWlyZWQ8T21pdDxHQ09wdGlvbnMsICdleHBpcmVzQXQnPj47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIC8vIGV2ZXJ5IDUgbWluXG4gICAgaW50ZXJ2YWxNUyA9IDYwICogMTAwMCAqIDUsXG4gICAgZXhwaXJ5TXVsdGlwbGllciA9IDIsXG4gICAgZXhwaXJlc0F0LFxuICB9OiBHQ09wdGlvbnMgPSB7fSkge1xuICAgIGlmIChleHBpcmVzQXQpIHtcbiAgICAgIHRoaXMuZXhwaXJlc0F0ID0gZXhwaXJlc0F0LmJpbmQodGhpcyk7XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgIGludGVydmFsTVMsXG4gICAgICBleHBpcnlNdWx0aXBsaWVyLFxuICAgIH07XG4gIH1cblxuICBpbml0KGNvbnRyb2xsZXI6IENvbnRyb2xsZXIpIHtcbiAgICB0aGlzLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuXG4gICAgdGhpcy5pbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5pZGxlQ2FsbGJhY2soKCkgPT4gdGhpcy5ydW5Td2VlcCgpLCB7IHRpbWVvdXQ6IDEwMDAgfSk7XG4gICAgfSwgdGhpcy5vcHRpb25zLmludGVydmFsTVMpO1xuICB9XG5cbiAgY2xlYW51cCgpIHtcbiAgICBjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWxJZCk7XG4gIH1cblxuICBjcmVhdGVDb3VudFJlZih7IGtleSwgcGF0aHMgPSBbXSB9OiB7IGtleT86IHN0cmluZzsgcGF0aHM/OiBFbnRpdHlQYXRoW10gfSkge1xuICAgIC8vIGluY3JlbWVudFxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAoa2V5KVxuICAgICAgICB0aGlzLmVuZHBvaW50Q291bnQuc2V0KGtleSwgKHRoaXMuZW5kcG9pbnRDb3VudC5nZXQoa2V5KSA/PyAwKSArIDEpO1xuICAgICAgcGF0aHMuZm9yRWFjaChwYXRoID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmVudGl0eUNvdW50LmhhcyhwYXRoLmtleSkpIHtcbiAgICAgICAgICB0aGlzLmVudGl0eUNvdW50LnNldChwYXRoLmtleSwgbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5zdGFuY2VDb3VudCA9IHRoaXMuZW50aXR5Q291bnQuZ2V0KHBhdGgua2V5KSE7XG4gICAgICAgIGluc3RhbmNlQ291bnQuc2V0KHBhdGgucGssIChpbnN0YW5jZUNvdW50LmdldChwYXRoLnBrKSA/PyAwKSArIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGRlY3JlbWVudFxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb3VudCA9IHRoaXMuZW5kcG9pbnRDb3VudC5nZXQoa2V5KSE7XG4gICAgICAgICAgaWYgKGN1cnJlbnRDb3VudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudENvdW50IDw9IDEpIHtcbiAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludENvdW50LmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgICAvLyBxdWV1ZSBmb3IgY2xlYW51cFxuICAgICAgICAgICAgICB0aGlzLmVuZHBvaW50c1EuYWRkKGtleSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmVuZHBvaW50Q291bnQuc2V0KGtleSwgY3VycmVudENvdW50IC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHBhdGhzLmZvckVhY2gocGF0aCA9PiB7XG4gICAgICAgICAgaWYgKCF0aGlzLmVudGl0eUNvdW50LmhhcyhwYXRoLmtleSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgaW5zdGFuY2VDb3VudCA9IHRoaXMuZW50aXR5Q291bnQuZ2V0KHBhdGgua2V5KSE7XG4gICAgICAgICAgY29uc3QgZW50aXR5Q291bnQgPSBpbnN0YW5jZUNvdW50LmdldChwYXRoLnBrKSE7XG4gICAgICAgICAgaWYgKGVudGl0eUNvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChlbnRpdHlDb3VudCA8PSAxKSB7XG4gICAgICAgICAgICAgIGluc3RhbmNlQ291bnQuZGVsZXRlKHBhdGgucGspO1xuICAgICAgICAgICAgICAvLyBxdWV1ZSBmb3IgY2xlYW51cFxuICAgICAgICAgICAgICB0aGlzLmVudGl0aWVzUS5wdXNoKHBhdGgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VDb3VudC5zZXQocGF0aC5waywgZW50aXR5Q291bnQgLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGV4cGlyZXNBdCh7XG4gICAgZmV0Y2hlZEF0LFxuICAgIGV4cGlyZXNBdCxcbiAgfToge1xuICAgIGV4cGlyZXNBdDogbnVtYmVyO1xuICAgIGRhdGU6IG51bWJlcjtcbiAgICBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgfSk6IG51bWJlciB7XG4gICAgcmV0dXJuIChcbiAgICAgIE1hdGgubWF4KFxuICAgICAgICAoZXhwaXJlc0F0IC0gZmV0Y2hlZEF0KSAqIHRoaXMub3B0aW9ucy5leHBpcnlNdWx0aXBsaWVyLFxuICAgICAgICAxMjAwMDAsXG4gICAgICApICsgZmV0Y2hlZEF0XG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBydW5Td2VlcCgpIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuY29udHJvbGxlci5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGVudGl0aWVzOiBFbnRpdHlQYXRoW10gPSBbXTtcbiAgICBjb25zdCBlbmRwb2ludHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGNvbnN0IG5leHRFbmRwb2ludHNRID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgdGhpcy5lbmRwb2ludHNRKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLmVuZHBvaW50Q291bnQuaGFzKGtleSkgJiZcbiAgICAgICAgdGhpcy5leHBpcmVzQXQoXG4gICAgICAgICAgc3RhdGUubWV0YVtrZXldID8/IHtcbiAgICAgICAgICAgIGZldGNoZWRBdDogMCxcbiAgICAgICAgICAgIGRhdGU6IDAsXG4gICAgICAgICAgICBleHBpcmVzQXQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA8IG5vd1xuICAgICAgKSB7XG4gICAgICAgIGVuZHBvaW50cy5wdXNoKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0RW5kcG9pbnRzUS5hZGQoa2V5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5lbmRwb2ludHNRID0gbmV4dEVuZHBvaW50c1E7XG5cbiAgICBjb25zdCBuZXh0RW50aXRpZXNROiBFbnRpdHlQYXRoW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgdGhpcy5lbnRpdGllc1EpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuZW50aXR5Q291bnQuZ2V0KHBhdGgua2V5KT8uaGFzKHBhdGgucGspICYmXG4gICAgICAgIHRoaXMuZXhwaXJlc0F0KFxuICAgICAgICAgIHN0YXRlLmVudGl0eU1ldGFbcGF0aC5rZXldPy5bcGF0aC5wa10gPz8ge1xuICAgICAgICAgICAgZmV0Y2hlZEF0OiAwLFxuICAgICAgICAgICAgZGF0ZTogMCxcbiAgICAgICAgICAgIGV4cGlyZXNBdDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICApIDwgbm93XG4gICAgICApIHtcbiAgICAgICAgZW50aXRpZXMucHVzaChwYXRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRFbnRpdGllc1EucHVzaChwYXRoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5lbnRpdGllc1EgPSBuZXh0RW50aXRpZXNRO1xuXG4gICAgaWYgKGVudGl0aWVzLmxlbmd0aCB8fCBlbmRwb2ludHMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmNvbnRyb2xsZXIuZGlzcGF0Y2goeyB0eXBlOiBHQywgZW50aXRpZXMsIGVuZHBvaW50cyB9KTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FsbHMgdGhlIGNhbGxiYWNrIHdoZW4gY2xpZW50IGlzIG5vdCAnYnVzeScgd2l0aCBoaWdoIHByaW9yaXR5IGludGVyYWN0aW9uIHRhc2tzXG4gICAqXG4gICAqIE92ZXJyaWRlIGZvciBwbGF0Zm9ybS1zcGVjaWZpYyBpbXBsZW1lbnRhdGlvbnNcbiAgICovXG4gIHByb3RlY3RlZCBpZGxlQ2FsbGJhY2soXG4gICAgY2FsbGJhY2s6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCxcbiAgICBvcHRpb25zPzogSWRsZVJlcXVlc3RPcHRpb25zLFxuICApIHtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcXVlc3RJZGxlQ2FsbGJhY2soY2FsbGJhY2ssIG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW1tb3J0YWxHQ1BvbGljeSBpbXBsZW1lbnRzIEdDSW50ZXJmYWNlIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBpbml0KCkge31cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBjbGVhbnVwKCkge31cbiAgY3JlYXRlQ291bnRSZWYoKSB7XG4gICAgcmV0dXJuICgpID0+ICgpID0+IHVuZGVmaW5lZDtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdDT3B0aW9ucyB7XG4gIGludGVydmFsTVM/OiBudW1iZXI7XG4gIGV4cGlyeU11bHRpcGxpZXI/OiBudW1iZXI7XG4gIGV4cGlyZXNBdD86IChtZXRhOiB7XG4gICAgZXhwaXJlc0F0OiBudW1iZXI7XG4gICAgZGF0ZTogbnVtYmVyO1xuICAgIGZldGNoZWRBdDogbnVtYmVyO1xuICB9KSA9PiBudW1iZXI7XG59XG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUNvdW50UmVmIHtcbiAgKHsga2V5LCBwYXRocyB9OiB7IGtleT86IHN0cmluZzsgcGF0aHM/OiBFbnRpdHlQYXRoW10gfSk6ICgpID0+ICgpID0+IHZvaWQ7XG59XG5leHBvcnQgaW50ZXJmYWNlIEdDSW50ZXJmYWNlIHtcbiAgY3JlYXRlQ291bnRSZWY6IENyZWF0ZUNvdW50UmVmO1xuICBpbml0KGNvbnRyb2xsZXI6IENvbnRyb2xsZXIpOiB2b2lkO1xuICBjbGVhbnVwKCk6IHZvaWQ7XG59XG4iXSwibWFw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