UNPKG

@atlaskit/editor-plugin-interactivity

Version:

Interactivity plugin for @atlaskit/editor-core

125 lines (118 loc) • 5.74 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.InteractionTracker = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _boundedMap = require("../collections/bounded-map"); var _interactionEvents = require("./interaction-events"); /** Optional so a `PerformanceEntry` is assignable without a cast: the DOM typings lack the field. */ /** Entries of one interaction arrive within it, so older than the last few hundred is not needed. */ var MAX_TRACKED = 256; /** * Makes interactions out of what the observer reports, for one session. Entries sharing a non-zero * `interactionId` — the browser's own definition of an interaction, the one INP filters on — are one * interaction whose latency is the maximum `duration` among them. They arrive incrementally, so a * latency can grow after it was first reported, and callers move what they counted rather than * counting the interaction twice. * * The editor's events answer what an entry cannot: which interactions were the editor's, and how * many there were, including the ones below the Event Timing reporting threshold. */ var InteractionTracker = exports.InteractionTracker = /*#__PURE__*/function () { /** * Both arguments keep the interactions of the previous session out of this one. * * @param startsAfterInteractionId the highest id the previous tracker saw. Without it, an entry * still arriving for that session's interaction would look new here and be counted twice. * @param startedAt when the session opened. No id can keep out an interaction started before the * first session of a page: Event Timing produces the entry after the event was presented, so the * click on Edit that mounted the editor reaches an observer which subscribed while its handler * ran. The page count the session started from has already counted it. */ function InteractionTracker() { var startsAfterInteractionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var startedAt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; (0, _classCallCheck2.default)(this, InteractionTracker); (0, _defineProperty2.default)(this, "interactions", new _boundedMap.BoundedMap(MAX_TRACKED)); (0, _defineProperty2.default)(this, "groupByEvent", new _boundedMap.BoundedMap(MAX_TRACKED)); (0, _defineProperty2.default)(this, "highestInteractionId", 0); this.startsAfterInteractionId = startsAfterInteractionId; this.startedAt = startedAt; } return (0, _createClass2.default)(InteractionTracker, [{ key: "lastInteractionId", get: function get() { return Math.max(this.highestInteractionId, this.startsAfterInteractionId); } /** * Merges an entry into the interaction it belongs to. * * @returns what that changed, or nothing when the entry belongs to no interaction of this * session or left the latency as it was. */ }, { key: "merge", value: function merge(entry) { if (!Number.isFinite(entry.duration) || entry.duration < 0) { return undefined; } var interactionId = entry.interactionId; if (!interactionId) { return undefined; } // Neither check covers the other: an entry is dated by its own event rather than by the // interaction, so the `keyup` of a press that rotated the session is dated after the // rotation, and the click that mounted the editor has no id to recognise it by. if (interactionId <= this.startsAfterInteractionId || entry.startTime < this.startedAt) { return undefined; } this.highestInteractionId = Math.max(this.highestInteractionId, interactionId); var tracked = this.interactions.get(interactionId); if (tracked === undefined) { // Taken once: an entry that only makes the interaction slower has to move its count // within the group it was counted in, not into another one. var group = this.groupByEvent.get((0, _interactionEvents.eventKey)(entry.name, entry.startTime)); var interaction = { group: group, latencyMs: entry.duration }; this.interactions.set(interactionId, interaction); return { type: 'new', interactionId: interactionId, latencyMs: interaction.latencyMs, group: group }; } // Not the slowest entry of the interaction, so its latency stands. if (entry.duration <= tracked.latencyMs) { return undefined; } var previousLatencyMs = tracked.latencyMs; tracked.latencyMs = entry.duration; return { type: 'remeasured', interactionId: interactionId, previousLatencyMs: previousLatencyMs, latencyMs: tracked.latencyMs, group: tracked.group }; } }, { key: "recordEditorEvent", value: function recordEditorEvent(event) { var kind = (0, _interactionEvents.interactionEventKind)(event.type); if (!kind) { return undefined; } // Every event of the interaction, because any of them can be the one Event Timing reports // as the slowest: for a pointer press that is usually the click. this.groupByEvent.set((0, _interactionEvents.eventKey)(event.type, event.timeStamp), kind.group); return kind.counts ? kind.group : undefined; } }]); }();