Skip to main content
Glama
mutation-rate-limiter.js5.23 kB
var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import { INCREMENTAL_SNAPSHOT_EVENT_TYPE, MUTATION_SOURCE_TYPE } from './sessionrecording-utils'; import { clampToRange } from '../../utils/number-utils'; var MutationRateLimiter = /** @class */ (function () { function MutationRateLimiter(rrweb, options) { if (options === void 0) { options = {}; } var _this = this; var _a, _b; this.rrweb = rrweb; this.options = options; this.bucketSize = 100; this.refillRate = 10; this.mutationBuckets = {}; this.loggedTracker = {}; this.refillBuckets = function () { Object.keys(_this.mutationBuckets).forEach(function (key) { _this.mutationBuckets[key] = _this.mutationBuckets[key] + _this.refillRate; if (_this.mutationBuckets[key] >= _this.bucketSize) { delete _this.mutationBuckets[key]; } }); }; this.getNodeOrRelevantParent = function (id) { // For some nodes we know they are part of a larger tree such as an SVG. // For those we want to block the entire node, not just the specific attribute var node = _this.rrweb.mirror.getNode(id); // Check if the node is an Element and then find the closest parent that is an SVG if ((node === null || node === void 0 ? void 0 : node.nodeName) !== 'svg' && node instanceof Element) { var closestSVG = node.closest('svg'); if (closestSVG) { return [_this.rrweb.mirror.getId(closestSVG), closestSVG]; } } return [id, node]; }; this.numberOfChanges = function (data) { var _a, _b, _c, _d, _e, _f, _g, _h; return (((_b = (_a = data.removes) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = data.attributes) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) + ((_f = (_e = data.texts) === null || _e === void 0 ? void 0 : _e.length) !== null && _f !== void 0 ? _f : 0) + ((_h = (_g = data.adds) === null || _g === void 0 ? void 0 : _g.length) !== null && _h !== void 0 ? _h : 0)); }; this.throttleMutations = function (event) { if (event.type !== INCREMENTAL_SNAPSHOT_EVENT_TYPE || event.data.source !== MUTATION_SOURCE_TYPE) { return event; } var data = event.data; var initialMutationCount = _this.numberOfChanges(data); if (data.attributes) { // Most problematic mutations come from attrs where the style or minor properties are changed rapidly data.attributes = data.attributes.filter(function (attr) { var _a, _b, _c; var _d = __read(_this.getNodeOrRelevantParent(attr.id), 2), nodeId = _d[0], node = _d[1]; if (_this.mutationBuckets[nodeId] === 0) { return false; } _this.mutationBuckets[nodeId] = (_a = _this.mutationBuckets[nodeId]) !== null && _a !== void 0 ? _a : _this.bucketSize; _this.mutationBuckets[nodeId] = Math.max(_this.mutationBuckets[nodeId] - 1, 0); if (_this.mutationBuckets[nodeId] === 0) { if (!_this.loggedTracker[nodeId]) { _this.loggedTracker[nodeId] = true; (_c = (_b = _this.options).onBlockedNode) === null || _c === void 0 ? void 0 : _c.call(_b, nodeId, node); } } return attr; }); } // Check if every part of the mutation is empty in which case there is nothing to do var mutationCount = _this.numberOfChanges(data); if (mutationCount === 0 && initialMutationCount !== mutationCount) { // If we have modified the mutation count and the remaining count is 0, then we don't need the event. return; } return event; }; this.refillRate = clampToRange((_a = this.options.refillRate) !== null && _a !== void 0 ? _a : this.refillRate, 0, 100, 'mutation throttling refill rate'); this.bucketSize = clampToRange((_b = this.options.bucketSize) !== null && _b !== void 0 ? _b : this.bucketSize, 0, 100, 'mutation throttling bucket size'); setInterval(function () { _this.refillBuckets(); }, 1000); } return MutationRateLimiter; }()); export { MutationRateLimiter }; //# sourceMappingURL=mutation-rate-limiter.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sadiuysal/mem0-mcp-server-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server