UNPKG

@atlaskit/editor-plugin-interactivity

Version:

Interactivity plugin for @atlaskit/editor-core

119 lines (112 loc) • 5.28 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { BoundedMap } from '../collections/bounded-map'; import { eventKey, interactionEventKind } from './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. */ export var 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; _classCallCheck(this, InteractionTracker); _defineProperty(this, "interactions", new BoundedMap(MAX_TRACKED)); _defineProperty(this, "groupByEvent", new BoundedMap(MAX_TRACKED)); _defineProperty(this, "highestInteractionId", 0); this.startsAfterInteractionId = startsAfterInteractionId; this.startedAt = startedAt; } return _createClass(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(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 = 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(eventKey(event.type, event.timeStamp), kind.group); return kind.counts ? kind.group : undefined; } }]); }();