UNPKG

@coralogix/browser

Version:

Official Coralogix SDK for browsers

1,686 lines 58 kB
import { __awaiter, __generator, __assign } from 'tslib';
import { C as CxGlobal, r as reportInternalEvent, g as getSdkConfig, S as SESSION_RECORDER_SEGMENTS_MAP, a as getNowTime, b as SESSION_RECORDING_NETWORK_ERR0R_MESSAGE, M as MAX_BATCH_TIME_MS, R as Request, c as SESSION_RECORDING_POSTFIX_URL, d as SESSION_RECORDING_DEFAULT_HEADERS, B as BATCH_TIME_DELAY, e as SESSION_RECORDER_KEY, f as MAX_MUTATIONS_FOR_SESSION_RECORDING, h as SESSION_RECORDING_DEFAULT_ERROR_MESSAGE } from './index.esm2.js';
import { record } from 'rrweb';
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
import '@opentelemetry/sdk-trace-base';
import '@opentelemetry/sdk-trace-web';
import '@opentelemetry/instrumentation';
import 'error-stack-parser';
import '@opentelemetry/instrumentation-fetch';
import '@opentelemetry/instrumentation-xml-http-request';
import 'web-vitals/attribution';
import '@opentelemetry/api';
import '@opentelemetry/propagator-b3';
import '@opentelemetry/propagator-aws-xray';

var EventType = /* @__PURE__ */ ((EventType2) => {
  EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
  EventType2[EventType2["Load"] = 1] = "Load";
  EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
  EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
  EventType2[EventType2["Meta"] = 4] = "Meta";
  EventType2[EventType2["Custom"] = 5] = "Custom";
  EventType2[EventType2["Plugin"] = 6] = "Plugin";
  return EventType2;
})(EventType || {});

var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
var NodeType = /* @__PURE__ */ ((NodeType2) => {
  NodeType2[NodeType2["Document"] = 0] = "Document";
  NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
  NodeType2[NodeType2["Element"] = 2] = "Element";
  NodeType2[NodeType2["Text"] = 3] = "Text";
  NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
  NodeType2[NodeType2["Comment"] = 5] = "Comment";
  return NodeType2;
})(NodeType || {});
function isElement(n) {
  return n.nodeType === n.ELEMENT_NODE;
}
function isShadowRoot(n) {
  const host = n == null ? undefined : n.host;
  return Boolean((host == null ? undefined : host.shadowRoot) === n);
}
function isNativeShadowDom(shadowRoot) {
  return Object.prototype.toString.call(shadowRoot) === "[object ShadowRoot]";
}
function fixBrowserCompatibilityIssuesInCSS(cssText) {
  if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
    cssText = cssText.replace(
      /\sbackground-clip:\s*text;/g,
      " -webkit-background-clip: text; background-clip: text;"
    );
  }
  return cssText;
}
function escapeImportStatement(rule) {
  const { cssText } = rule;
  if (cssText.split('"').length < 3)
    return cssText;
  const statement = ["@import", `url(${JSON.stringify(rule.href)})`];
  if (rule.layerName === "") {
    statement.push(`layer`);
  } else if (rule.layerName) {
    statement.push(`layer(${rule.layerName})`);
  }
  if (rule.supportsText) {
    statement.push(`supports(${rule.supportsText})`);
  }
  if (rule.media.length) {
    statement.push(rule.media.mediaText);
  }
  return statement.join(" ") + ";";
}
function stringifyStylesheet(s) {
  try {
    const rules = s.rules || s.cssRules;
    return rules ? fixBrowserCompatibilityIssuesInCSS(
      Array.from(rules, stringifyRule).join("")
    ) : null;
  } catch (error) {
    return null;
  }
}
function stringifyRule(rule) {
  let importStringified;
  if (isCSSImportRule(rule)) {
    try {
      importStringified = // for same-origin stylesheets,
      // we can access the imported stylesheet rules directly
      stringifyStylesheet(rule.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
      escapeImportStatement(rule);
    } catch (error) {
    }
  } else if (isCSSStyleRule(rule) && rule.selectorText.includes(":")) {
    return fixSafariColons(rule.cssText);
  }
  return importStringified || rule.cssText;
}
function fixSafariColons(cssStringified) {
  const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
  return cssStringified.replace(regex, "$1\\$2");
}
function isCSSImportRule(rule) {
  return "styleSheet" in rule;
}
function isCSSStyleRule(rule) {
  return "selectorText" in rule;
}
class Mirror {
  constructor() {
    __publicField(this, "idNodeMap", /* @__PURE__ */ new Map());
    __publicField(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
  }
  getId(n) {
    var _a;
    if (!n)
      return -1;
    const id = (_a = this.getMeta(n)) == null ? undefined : _a.id;
    return id ?? -1;
  }
  getNode(id) {
    return this.idNodeMap.get(id) || null;
  }
  getIds() {
    return Array.from(this.idNodeMap.keys());
  }
  getMeta(n) {
    return this.nodeMetaMap.get(n) || null;
  }
  // removes the node from idNodeMap
  // doesn't remove the node from nodeMetaMap
  removeNodeFromMap(n) {
    const id = this.getId(n);
    this.idNodeMap.delete(id);
    if (n.childNodes) {
      n.childNodes.forEach(
        (childNode) => this.removeNodeFromMap(childNode)
      );
    }
  }
  has(id) {
    return this.idNodeMap.has(id);
  }
  hasNode(node) {
    return this.nodeMetaMap.has(node);
  }
  add(n, meta) {
    const id = meta.id;
    this.idNodeMap.set(id, n);
    this.nodeMetaMap.set(n, meta);
  }
  replace(id, n) {
    const oldNode = this.getNode(id);
    if (oldNode) {
      const meta = this.nodeMetaMap.get(oldNode);
      if (meta)
        this.nodeMetaMap.set(n, meta);
    }
    this.idNodeMap.set(id, n);
  }
  reset() {
    this.idNodeMap = /* @__PURE__ */ new Map();
    this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
  }
}
function maskInputValue({
  element,
  maskInputOptions,
  tagName,
  type,
  value,
  maskInputFn
}) {
  let text = value || "";
  const actualType = type && toLowerCase(type);
  if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {
    if (maskInputFn) {
      text = maskInputFn(text, element);
    } else {
      text = "*".repeat(text.length);
    }
  }
  return text;
}
function toLowerCase(str) {
  return str.toLowerCase();
}
const ORIGINAL_ATTRIBUTE_NAME = "__rrweb_original__";
function is2DCanvasBlank(canvas) {
  const ctx = canvas.getContext("2d");
  if (!ctx)
    return true;
  const chunkSize = 50;
  for (let x = 0; x < canvas.width; x += chunkSize) {
    for (let y = 0; y < canvas.height; y += chunkSize) {
      const getImageData = ctx.getImageData;
      const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;
      const pixelBuffer = new Uint32Array(
        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
        originalGetImageData.call(
          ctx,
          x,
          y,
          Math.min(chunkSize, canvas.width - x),
          Math.min(chunkSize, canvas.height - y)
        ).data.buffer
      );
      if (pixelBuffer.some((pixel) => pixel !== 0))
        return false;
    }
  }
  return true;
}
function getInputType(element) {
  const type = element.type;
  return element.hasAttribute("data-rr-is-password") ? "password" : type ? (
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
    toLowerCase(type)
  ) : null;
}
function extractFileExtension(path, baseURL) {
  let url;
  try {
    url = new URL(path, baseURL ?? window.location.href);
  } catch (err) {
    return null;
  }
  const regex = /\.([0-9a-z]+)(?:$)/i;
  const match = url.pathname.match(regex);
  return (match == null ? undefined : match[1]) ?? null;
}
let _id = 1;
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
const IGNORED_NODE = -2;
function genId() {
  return _id++;
}
function getValidTagName(element) {
  if (element instanceof HTMLFormElement) {
    return "form";
  }
  const processedTagName = toLowerCase(element.tagName);
  if (tagNameRegex.test(processedTagName)) {
    return "div";
  }
  return processedTagName;
}
function extractOrigin(url) {
  let origin = "";
  if (url.indexOf("//") > -1) {
    origin = url.split("/").slice(0, 3).join("/");
  } else {
    origin = url.split("/")[0];
  }
  origin = origin.split("?")[0];
  return origin;
}
let canvasService;
let canvasCtx;
const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
const URL_WWW_MATCH = /^www\..*/i;
const DATA_URI = /^(data:)([^,]*),(.*)/i;
function absoluteToStylesheet(cssText, href) {
  return (cssText || "").replace(
    URL_IN_CSS_REF,
    (origin, quote1, path1, quote2, path2, path3) => {
      const filePath = path1 || path2 || path3;
      const maybeQuote = quote1 || quote2 || "";
      if (!filePath) {
        return origin;
      }
      if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
        return `url(${maybeQuote}${filePath}${maybeQuote})`;
      }
      if (DATA_URI.test(filePath)) {
        return `url(${maybeQuote}${filePath}${maybeQuote})`;
      }
      if (filePath[0] === "/") {
        return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;
      }
      const stack = href.split("/");
      const parts = filePath.split("/");
      stack.pop();
      for (const part of parts) {
        if (part === ".") {
          continue;
        } else if (part === "..") {
          stack.pop();
        } else {
          stack.push(part);
        }
      }
      return `url(${maybeQuote}${stack.join("/")}${maybeQuote})`;
    }
  );
}
const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
function getAbsoluteSrcsetString(doc, attributeValue) {
  if (attributeValue.trim() === "") {
    return attributeValue;
  }
  let pos = 0;
  function collectCharacters(regEx) {
    let chars;
    const match = regEx.exec(attributeValue.substring(pos));
    if (match) {
      chars = match[0];
      pos += chars.length;
      return chars;
    }
    return "";
  }
  const output = [];
  while (true) {
    collectCharacters(SRCSET_COMMAS_OR_SPACES);
    if (pos >= attributeValue.length) {
      break;
    }
    let url = collectCharacters(SRCSET_NOT_SPACES);
    if (url.slice(-1) === ",") {
      url = absoluteToDoc(doc, url.substring(0, url.length - 1));
      output.push(url);
    } else {
      let descriptorsStr = "";
      url = absoluteToDoc(doc, url);
      let inParens = false;
      while (true) {
        const c = attributeValue.charAt(pos);
        if (c === "") {
          output.push((url + descriptorsStr).trim());
          break;
        } else if (!inParens) {
          if (c === ",") {
            pos += 1;
            output.push((url + descriptorsStr).trim());
            break;
          } else if (c === "(") {
            inParens = true;
          }
        } else {
          if (c === ")") {
            inParens = false;
          }
        }
        descriptorsStr += c;
        pos += 1;
      }
    }
  }
  return output.join(", ");
}
const cachedDocument = /* @__PURE__ */ new WeakMap();
function absoluteToDoc(doc, attributeValue) {
  if (!attributeValue || attributeValue.trim() === "") {
    return attributeValue;
  }
  return getHref(doc, attributeValue);
}
function isSVGElement(el) {
  return Boolean(el.tagName === "svg" || el.ownerSVGElement);
}
function getHref(doc, customHref) {
  let a = cachedDocument.get(doc);
  if (!a) {
    a = doc.createElement("a");
    cachedDocument.set(doc, a);
  }
  if (!customHref) {
    customHref = "";
  } else if (customHref.startsWith("blob:") || customHref.startsWith("data:")) {
    return customHref;
  }
  a.setAttribute("href", customHref);
  return a.href;
}
function transformAttribute(doc, tagName, name, value) {
  if (!value) {
    return value;
  }
  if (name === "src" || name === "href" && !(tagName === "use" && value[0] === "#")) {
    return absoluteToDoc(doc, value);
  } else if (name === "xlink:href" && value[0] !== "#") {
    return absoluteToDoc(doc, value);
  } else if (name === "background" && (tagName === "table" || tagName === "td" || tagName === "th")) {
    return absoluteToDoc(doc, value);
  } else if (name === "srcset") {
    return getAbsoluteSrcsetString(doc, value);
  } else if (name === "style") {
    return absoluteToStylesheet(value, getHref(doc));
  } else if (tagName === "object" && name === "data") {
    return absoluteToDoc(doc, value);
  }
  return value;
}
function ignoreAttribute(tagName, name, _value) {
  return (tagName === "video" || tagName === "audio") && name === "autoplay";
}
function _isBlockedElement(element, blockClass, blockSelector) {
  try {
    if (typeof blockClass === "string") {
      if (element.classList.contains(blockClass)) {
        return true;
      }
    } else {
      for (let eIndex = element.classList.length; eIndex--; ) {
        const className = element.classList[eIndex];
        if (blockClass.test(className)) {
          return true;
        }
      }
    }
    if (blockSelector) {
      return element.matches(blockSelector);
    }
  } catch (e) {
  }
  return false;
}
function classMatchesRegex(node, regex, checkAncestors) {
  if (!node)
    return false;
  if (node.nodeType !== node.ELEMENT_NODE) {
    if (!checkAncestors)
      return false;
    return classMatchesRegex(node.parentNode, regex, checkAncestors);
  }
  for (let eIndex = node.classList.length; eIndex--; ) {
    const className = node.classList[eIndex];
    if (regex.test(className)) {
      return true;
    }
  }
  if (!checkAncestors)
    return false;
  return classMatchesRegex(node.parentNode, regex, checkAncestors);
}
function needMaskingText(node, maskTextClass, maskTextSelector, checkAncestors) {
  try {
    const el = node.nodeType === node.ELEMENT_NODE ? node : node.parentElement;
    if (el === null)
      return false;
    if (typeof maskTextClass === "string") {
      if (checkAncestors) {
        if (el.closest(`.${maskTextClass}`))
          return true;
      } else {
        if (el.classList.contains(maskTextClass))
          return true;
      }
    } else {
      if (classMatchesRegex(el, maskTextClass, checkAncestors))
        return true;
    }
    if (maskTextSelector) {
      if (checkAncestors) {
        if (el.closest(maskTextSelector))
          return true;
      } else {
        if (el.matches(maskTextSelector))
          return true;
      }
    }
  } catch (e) {
  }
  return false;
}
function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
  const win = iframeEl.contentWindow;
  if (!win) {
    return;
  }
  let fired = false;
  let readyState;
  try {
    readyState = win.document.readyState;
  } catch (error) {
    return;
  }
  if (readyState !== "complete") {
    const timer = setTimeout(() => {
      if (!fired) {
        listener();
        fired = true;
      }
    }, iframeLoadTimeout);
    iframeEl.addEventListener("load", () => {
      clearTimeout(timer);
      fired = true;
      listener();
    });
    return;
  }
  const blankUrl = "about:blank";
  if (win.location.href !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === "") {
    setTimeout(listener, 0);
    return iframeEl.addEventListener("load", listener);
  }
  iframeEl.addEventListener("load", listener);
}
function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
  let fired = false;
  let styleSheetLoaded;
  try {
    styleSheetLoaded = link.sheet;
  } catch (error) {
    return;
  }
  if (styleSheetLoaded)
    return;
  const timer = setTimeout(() => {
    if (!fired) {
      listener();
      fired = true;
    }
  }, styleSheetLoadTimeout);
  link.addEventListener("load", () => {
    clearTimeout(timer);
    fired = true;
    listener();
  });
}
function serializeNode(n, options) {
  const {
    doc,
    mirror,
    blockClass,
    blockSelector,
    needsMask,
    inlineStylesheet,
    maskInputOptions = {},
    maskTextFn,
    maskInputFn,
    dataURLOptions = {},
    inlineImages,
    recordCanvas,
    keepIframeSrcFn,
    newlyAddedElement = false
  } = options;
  const rootId = getRootId(doc, mirror);
  switch (n.nodeType) {
    case n.DOCUMENT_NODE:
      if (n.compatMode !== "CSS1Compat") {
        return {
          type: NodeType.Document,
          childNodes: [],
          compatMode: n.compatMode
          // probably "BackCompat"
        };
      } else {
        return {
          type: NodeType.Document,
          childNodes: []
        };
      }
    case n.DOCUMENT_TYPE_NODE:
      return {
        type: NodeType.DocumentType,
        name: n.name,
        publicId: n.publicId,
        systemId: n.systemId,
        rootId
      };
    case n.ELEMENT_NODE:
      return serializeElementNode(n, {
        doc,
        blockClass,
        blockSelector,
        inlineStylesheet,
        maskInputOptions,
        maskInputFn,
        dataURLOptions,
        inlineImages,
        recordCanvas,
        keepIframeSrcFn,
        newlyAddedElement,
        rootId
      });
    case n.TEXT_NODE:
      return serializeTextNode(n, {
        doc,
        needsMask,
        maskTextFn,
        rootId
      });
    case n.CDATA_SECTION_NODE:
      return {
        type: NodeType.CDATA,
        textContent: "",
        rootId
      };
    case n.COMMENT_NODE:
      return {
        type: NodeType.Comment,
        textContent: n.textContent || "",
        rootId
      };
    default:
      return false;
  }
}
function getRootId(doc, mirror) {
  if (!mirror.hasNode(doc))
    return undefined;
  const docId = mirror.getId(doc);
  return docId === 1 ? undefined : docId;
}
function serializeTextNode(n, options) {
  var _a;
  const { needsMask, maskTextFn, rootId } = options;
  const parentTagName = n.parentNode && n.parentNode.tagName;
  let textContent = n.textContent;
  const isStyle = parentTagName === "STYLE" ? true : undefined;
  const isScript = parentTagName === "SCRIPT" ? true : undefined;
  if (isStyle && textContent) {
    try {
      if (n.nextSibling || n.previousSibling) {
      } else if ((_a = n.parentNode.sheet) == null ? void 0 : _a.cssRules) {
        textContent = stringifyStylesheet(
          n.parentNode.sheet
        );
      }
    } catch (err) {
      console.warn(
        `Cannot get CSS styles from text's parentNode. Error: ${err}`,
        n
      );
    }
    textContent = absoluteToStylesheet(textContent, getHref(options.doc));
  }
  if (isScript) {
    textContent = "SCRIPT_PLACEHOLDER";
  }
  if (!isStyle && !isScript && textContent && needsMask) {
    textContent = maskTextFn ? maskTextFn(textContent, n.parentElement) : textContent.replace(/[\S]/g, "*");
  }
  return {
    type: NodeType.Text,
    textContent: textContent || "",
    isStyle,
    rootId
  };
}
function serializeElementNode(n, options) {
  const {
    doc,
    blockClass,
    blockSelector,
    inlineStylesheet,
    maskInputOptions = {},
    maskInputFn,
    dataURLOptions = {},
    inlineImages,
    recordCanvas,
    keepIframeSrcFn,
    newlyAddedElement = false,
    rootId
  } = options;
  const needBlock = _isBlockedElement(n, blockClass, blockSelector);
  const tagName = getValidTagName(n);
  let attributes2 = {};
  const len = n.attributes.length;
  for (let i = 0; i < len; i++) {
    const attr = n.attributes[i];
    if (!ignoreAttribute(tagName, attr.name, attr.value)) {
      attributes2[attr.name] = transformAttribute(
        doc,
        tagName,
        toLowerCase(attr.name),
        attr.value
      );
    }
  }
  if (tagName === "link" && inlineStylesheet) {
    const stylesheet = Array.from(doc.styleSheets).find((s) => {
      return s.href === n.href;
    });
    let cssText = null;
    if (stylesheet) {
      cssText = stringifyStylesheet(stylesheet);
    }
    if (cssText) {
      delete attributes2.rel;
      delete attributes2.href;
      attributes2._cssText = absoluteToStylesheet(cssText, stylesheet.href);
    }
  }
  if (tagName === "style" && n.sheet && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element
  !(n.innerText || n.textContent || "").trim().length) {
    const cssText = stringifyStylesheet(
      n.sheet
    );
    if (cssText) {
      attributes2._cssText = absoluteToStylesheet(cssText, getHref(doc));
    }
  }
  if (tagName === "input" || tagName === "textarea" || tagName === "select") {
    const value = n.value;
    const checked = n.checked;
    if (attributes2.type !== "radio" && attributes2.type !== "checkbox" && attributes2.type !== "submit" && attributes2.type !== "button" && value) {
      attributes2.value = maskInputValue({
        element: n,
        type: getInputType(n),
        tagName,
        value,
        maskInputOptions,
        maskInputFn
      });
    } else if (checked) {
      attributes2.checked = checked;
    }
  }
  if (tagName === "option") {
    if (n.selected && !maskInputOptions["select"]) {
      attributes2.selected = true;
    } else {
      delete attributes2.selected;
    }
  }
  if (tagName === "canvas" && recordCanvas) {
    if (n.__context === "2d") {
      if (!is2DCanvasBlank(n)) {
        attributes2.rr_dataURL = n.toDataURL(
          dataURLOptions.type,
          dataURLOptions.quality
        );
      }
    } else if (!("__context" in n)) {
      const canvasDataURL = n.toDataURL(
        dataURLOptions.type,
        dataURLOptions.quality
      );
      const blankCanvas = doc.createElement("canvas");
      blankCanvas.width = n.width;
      blankCanvas.height = n.height;
      const blankCanvasDataURL = blankCanvas.toDataURL(
        dataURLOptions.type,
        dataURLOptions.quality
      );
      if (canvasDataURL !== blankCanvasDataURL) {
        attributes2.rr_dataURL = canvasDataURL;
      }
    }
  }
  if (tagName === "img" && inlineImages) {
    if (!canvasService) {
      canvasService = doc.createElement("canvas");
      canvasCtx = canvasService.getContext("2d");
    }
    const image = n;
    const imageSrc = image.currentSrc || image.getAttribute("src") || "<unknown-src>";
    const priorCrossOrigin = image.crossOrigin;
    const recordInlineImage = () => {
      image.removeEventListener("load", recordInlineImage);
      try {
        canvasService.width = image.naturalWidth;
        canvasService.height = image.naturalHeight;
        canvasCtx.drawImage(image, 0, 0);
        attributes2.rr_dataURL = canvasService.toDataURL(
          dataURLOptions.type,
          dataURLOptions.quality
        );
      } catch (err) {
        if (image.crossOrigin !== "anonymous") {
          image.crossOrigin = "anonymous";
          if (image.complete && image.naturalWidth !== 0)
            recordInlineImage();
          else
            image.addEventListener("load", recordInlineImage);
          return;
        } else {
          console.warn(
            `Cannot inline img src=${imageSrc}! Error: ${err}`
          );
        }
      }
      if (image.crossOrigin === "anonymous") {
        priorCrossOrigin ? attributes2.crossOrigin = priorCrossOrigin : image.removeAttribute("crossorigin");
      }
    };
    if (image.complete && image.naturalWidth !== 0)
      recordInlineImage();
    else
      image.addEventListener("load", recordInlineImage);
  }
  if (tagName === "audio" || tagName === "video") {
    const mediaAttributes = attributes2;
    mediaAttributes.rr_mediaState = n.paused ? "paused" : "played";
    mediaAttributes.rr_mediaCurrentTime = n.currentTime;
    mediaAttributes.rr_mediaPlaybackRate = n.playbackRate;
    mediaAttributes.rr_mediaMuted = n.muted;
    mediaAttributes.rr_mediaLoop = n.loop;
    mediaAttributes.rr_mediaVolume = n.volume;
  }
  if (!newlyAddedElement) {
    if (n.scrollLeft) {
      attributes2.rr_scrollLeft = n.scrollLeft;
    }
    if (n.scrollTop) {
      attributes2.rr_scrollTop = n.scrollTop;
    }
  }
  if (needBlock) {
    const { width, height } = n.getBoundingClientRect();
    attributes2 = {
      class: attributes2.class,
      rr_width: `${width}px`,
      rr_height: `${height}px`
    };
  }
  if (tagName === "iframe" && !keepIframeSrcFn(attributes2.src)) {
    if (!n.contentDocument) {
      attributes2.rr_src = attributes2.src;
    }
    delete attributes2.src;
  }
  let isCustomElement;
  try {
    if (customElements.get(tagName))
      isCustomElement = true;
  } catch (e) {
  }
  return {
    type: NodeType.Element,
    tagName,
    attributes: attributes2,
    childNodes: [],
    isSVG: isSVGElement(n) || undefined,
    needBlock,
    rootId,
    isCustom: isCustomElement
  };
}
function lowerIfExists(maybeAttr) {
  if (maybeAttr === undefined || maybeAttr === null) {
    return "";
  } else {
    return maybeAttr.toLowerCase();
  }
}
function slimDOMExcluded(sn, slimDOMOptions) {
  if (slimDOMOptions.comment && sn.type === NodeType.Comment) {
    return true;
  } else if (sn.type === NodeType.Element) {
    if (slimDOMOptions.script && // script tag
    (sn.tagName === "script" || // (module)preload link
    sn.tagName === "link" && (sn.attributes.rel === "preload" || sn.attributes.rel === "modulepreload") && sn.attributes.as === "script" || // prefetch link
    sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) {
      return true;
    } else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
      /^msapplication-tile(image|color)$/
    ) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) {
      return true;
    } else if (sn.tagName === "meta") {
      if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
        return true;
      } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)
      lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === "pinterest")) {
        return true;
      } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === "robots" || lowerIfExists(sn.attributes.name) === "googlebot" || lowerIfExists(sn.attributes.name) === "bingbot")) {
        return true;
      } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes["http-equiv"] !== undefined) {
        return true;
      } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === "author" || lowerIfExists(sn.attributes.name) === "generator" || lowerIfExists(sn.attributes.name) === "framework" || lowerIfExists(sn.attributes.name) === "publisher" || lowerIfExists(sn.attributes.name) === "progid" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
        return true;
      } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === "google-site-verification" || lowerIfExists(sn.attributes.name) === "yandex-verification" || lowerIfExists(sn.attributes.name) === "csrf-token" || lowerIfExists(sn.attributes.name) === "p:domain_verify" || lowerIfExists(sn.attributes.name) === "verify-v1" || lowerIfExists(sn.attributes.name) === "verification" || lowerIfExists(sn.attributes.name) === "shopify-checkout-api-token")) {
        return true;
      }
    }
  }
  return false;
}
function serializeNodeWithId(n, options) {
  const {
    doc,
    mirror,
    blockClass,
    blockSelector,
    maskTextClass,
    maskTextSelector,
    skipChild = false,
    inlineStylesheet = true,
    maskInputOptions = {},
    maskTextFn,
    maskInputFn,
    slimDOMOptions,
    dataURLOptions = {},
    inlineImages = false,
    recordCanvas = false,
    onSerialize,
    onIframeLoad,
    iframeLoadTimeout = 5e3,
    onStylesheetLoad,
    stylesheetLoadTimeout = 5e3,
    keepIframeSrcFn = () => false,
    newlyAddedElement = false
  } = options;
  let { needsMask } = options;
  let { preserveWhiteSpace = true } = options;
  if (!needsMask && n.childNodes) {
    const checkAncestors = needsMask === undefined;
    needsMask = needMaskingText(
      n,
      maskTextClass,
      maskTextSelector,
      checkAncestors
    );
  }
  const _serializedNode = serializeNode(n, {
    doc,
    mirror,
    blockClass,
    blockSelector,
    needsMask,
    inlineStylesheet,
    maskInputOptions,
    maskTextFn,
    maskInputFn,
    dataURLOptions,
    inlineImages,
    recordCanvas,
    keepIframeSrcFn,
    newlyAddedElement
  });
  if (!_serializedNode) {
    console.warn(n, "not serialized");
    return null;
  }
  let id;
  if (mirror.hasNode(n)) {
    id = mirror.getId(n);
  } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType.Text && !_serializedNode.isStyle && !_serializedNode.textContent.replace(/^\s+|\s+$/gm, "").length) {
    id = IGNORED_NODE;
  } else {
    id = genId();
  }
  const serializedNode2 = Object.assign(_serializedNode, { id });
  mirror.add(n, serializedNode2);
  if (id === IGNORED_NODE) {
    return null;
  }
  if (onSerialize) {
    onSerialize(n);
  }
  let recordChild = !skipChild;
  if (serializedNode2.type === NodeType.Element) {
    recordChild = recordChild && !serializedNode2.needBlock;
    delete serializedNode2.needBlock;
    const shadowRoot = n.shadowRoot;
    if (shadowRoot && isNativeShadowDom(shadowRoot))
      serializedNode2.isShadowHost = true;
  }
  if ((serializedNode2.type === NodeType.Document || serializedNode2.type === NodeType.Element) && recordChild) {
    if (slimDOMOptions.headWhitespace && serializedNode2.type === NodeType.Element && serializedNode2.tagName === "head") {
      preserveWhiteSpace = false;
    }
    const bypassOptions = {
      doc,
      mirror,
      blockClass,
      blockSelector,
      needsMask,
      maskTextClass,
      maskTextSelector,
      skipChild,
      inlineStylesheet,
      maskInputOptions,
      maskTextFn,
      maskInputFn,
      slimDOMOptions,
      dataURLOptions,
      inlineImages,
      recordCanvas,
      preserveWhiteSpace,
      onSerialize,
      onIframeLoad,
      iframeLoadTimeout,
      onStylesheetLoad,
      stylesheetLoadTimeout,
      keepIframeSrcFn
    };
    if (serializedNode2.type === NodeType.Element && serializedNode2.tagName === "textarea" && serializedNode2.attributes.value !== undefined)
      ;
    else {
      for (const childN of Array.from(n.childNodes)) {
        const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
        if (serializedChildNode) {
          serializedNode2.childNodes.push(serializedChildNode);
        }
      }
    }
    if (isElement(n) && n.shadowRoot) {
      for (const childN of Array.from(n.shadowRoot.childNodes)) {
        const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
        if (serializedChildNode) {
          isNativeShadowDom(n.shadowRoot) && (serializedChildNode.isShadow = true);
          serializedNode2.childNodes.push(serializedChildNode);
        }
      }
    }
  }
  if (n.parentNode && isShadowRoot(n.parentNode) && isNativeShadowDom(n.parentNode)) {
    serializedNode2.isShadow = true;
  }
  if (serializedNode2.type === NodeType.Element && serializedNode2.tagName === "iframe") {
    onceIframeLoaded(
      n,
      () => {
        const iframeDoc = n.contentDocument;
        if (iframeDoc && onIframeLoad) {
          const serializedIframeNode = serializeNodeWithId(iframeDoc, {
            doc: iframeDoc,
            mirror,
            blockClass,
            blockSelector,
            needsMask,
            maskTextClass,
            maskTextSelector,
            skipChild: false,
            inlineStylesheet,
            maskInputOptions,
            maskTextFn,
            maskInputFn,
            slimDOMOptions,
            dataURLOptions,
            inlineImages,
            recordCanvas,
            preserveWhiteSpace,
            onSerialize,
            onIframeLoad,
            iframeLoadTimeout,
            onStylesheetLoad,
            stylesheetLoadTimeout,
            keepIframeSrcFn
          });
          if (serializedIframeNode) {
            onIframeLoad(
              n,
              serializedIframeNode
            );
          }
        }
      },
      iframeLoadTimeout
    );
  }
  if (serializedNode2.type === NodeType.Element && serializedNode2.tagName === "link" && typeof serializedNode2.attributes.rel === "string" && (serializedNode2.attributes.rel === "stylesheet" || serializedNode2.attributes.rel === "preload" && typeof serializedNode2.attributes.href === "string" && extractFileExtension(serializedNode2.attributes.href) === "css")) {
    onceStylesheetLoaded(
      n,
      () => {
        if (onStylesheetLoad) {
          const serializedLinkNode = serializeNodeWithId(n, {
            doc,
            mirror,
            blockClass,
            blockSelector,
            needsMask,
            maskTextClass,
            maskTextSelector,
            skipChild: false,
            inlineStylesheet,
            maskInputOptions,
            maskTextFn,
            maskInputFn,
            slimDOMOptions,
            dataURLOptions,
            inlineImages,
            recordCanvas,
            preserveWhiteSpace,
            onSerialize,
            onIframeLoad,
            iframeLoadTimeout,
            onStylesheetLoad,
            stylesheetLoadTimeout,
            keepIframeSrcFn
          });
          if (serializedLinkNode) {
            onStylesheetLoad(
              n,
              serializedLinkNode
            );
          }
        }
      },
      stylesheetLoadTimeout
    );
  }
  return serializedNode2;
}
function snapshot(n, options) {
  const {
    mirror = new Mirror(),
    blockClass = "rr-block",
    blockSelector = null,
    maskTextClass = "rr-mask",
    maskTextSelector = null,
    inlineStylesheet = true,
    inlineImages = false,
    recordCanvas = false,
    maskAllInputs = false,
    maskTextFn,
    maskInputFn,
    slimDOM = false,
    dataURLOptions,
    preserveWhiteSpace,
    onSerialize,
    onIframeLoad,
    iframeLoadTimeout,
    onStylesheetLoad,
    stylesheetLoadTimeout,
    keepIframeSrcFn = () => false
  } = options || {};
  const maskInputOptions = maskAllInputs === true ? {
    color: true,
    date: true,
    "datetime-local": true,
    email: true,
    month: true,
    number: true,
    range: true,
    search: true,
    tel: true,
    text: true,
    time: true,
    url: true,
    week: true,
    textarea: true,
    select: true,
    password: true
  } : maskAllInputs === false ? {
    password: true
  } : maskAllInputs;
  const slimDOMOptions = slimDOM === true || slimDOM === "all" ? (
    // if true: set of sensible options that should not throw away any information
    {
      script: true,
      comment: true,
      headFavicon: true,
      headWhitespace: true,
      headMetaDescKeywords: slimDOM === "all",
      // destructive
      headMetaSocial: true,
      headMetaRobots: true,
      headMetaHttpEquiv: true,
      headMetaAuthorship: true,
      headMetaVerification: true
    }
  ) : slimDOM === false ? {} : slimDOM;
  return serializeNodeWithId(n, {
    doc: n,
    mirror,
    blockClass,
    blockSelector,
    maskTextClass,
    maskTextSelector,
    skipChild: false,
    inlineStylesheet,
    maskInputOptions,
    maskTextFn,
    maskInputFn,
    slimDOMOptions,
    dataURLOptions,
    inlineImages,
    recordCanvas,
    preserveWhiteSpace,
    onSerialize,
    onIframeLoad,
    iframeLoadTimeout,
    onStylesheetLoad,
    stylesheetLoadTimeout,
    keepIframeSrcFn,
    newlyAddedElement: false
  });
}

// @ts-nocheck
function getWorkerString() {
    var _this = this;
    var MAX_CHUNK_SIZE = 1024 * 1024; //1MB
    var ERROR_MESSAGE = 'Coralogix Browser SDK - Error from session recording worker:\n';
    importScriptWithFallback('https://cdn.rum-ingress-coralogix.com/coralogix/browser/latest/pako_deflate.es5.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako_deflate.es5.min.js');
    self.onmessage = function (_a) {
        var data = _a.data;
        if (!_this.pako) {
            console.warn('Coralogix Browser SDK - Web worker not created due to missing pako library');
            self.postMessage({
                event: 'stopRecording',
            });
            return;
        }
        var recordsData;
        var isScreenshot = !!data.screenshotId;
        if (isScreenshot) {
            recordsData = JSON.stringify(data.records);
        }
        else {
            recordsData = omitSquareBrackets(JSON.stringify(data.records));
        }
        var sessionId = data.sessionId;
        var sessionCreationDate = data.sessionCreationDate;
        var screenshotId = data.screenshotId;
        var gzipData = _this.pako.gzip(recordsData);
        var gzipSize = gzipData.byteLength;
        if (gzipSize >= MAX_CHUNK_SIZE) {
            var totalChunks = Math.ceil(gzipSize / MAX_CHUNK_SIZE);
            for (var i = 0; i < totalChunks; i++) {
                var start = i * MAX_CHUNK_SIZE;
                var end = (i + 1) * MAX_CHUNK_SIZE;
                var chunk = gzipData.slice(start, end);
                createBlobAndSend(sessionId, sessionCreationDate, chunk, i, totalChunks - 1, screenshotId, 'splitRecordData');
            }
        }
        else {
            createBlobAndSend(sessionId, sessionCreationDate, gzipData, undefined, undefined, screenshotId);
        }
    };
    self.onerror = function (err) {
        console.warn(ERROR_MESSAGE, err);
        self.postMessage({
            event: 'stopRecording',
        });
    };
    function omitSquareBrackets(json) {
        return json.slice(1, -1);
    }
    function importScriptWithFallback(url, fallbackUrl) {
        try {
            importScripts(url);
        }
        catch (err) {
            try {
                importScripts(fallbackUrl);
            }
            catch (fallbackErr) {
                self.postMessage({ event: 'stopRecording' });
            }
        }
    }
    function createBlobAndSend(sessionId, sessionCreationDate, gzipData, chunkIndex, totalChunks, screenshotId, event) {
        if (event === undefined) { event = 'sendRecordData'; }
        var blob = new Blob([gzipData], {
            type: 'application/octet-stream',
        });
        self.postMessage({
            sessionId: sessionId,
            sessionCreationDate: sessionCreationDate,
            gzipBlob: blob,
            chunkIndex: chunkIndex,
            totalChunks: totalChunks,
            screenshotId: screenshotId,
            event: event,
        });
    }
}

var WorkerManager = /** @class */ (function () {
    function WorkerManager() {
    }
    WorkerManager.prototype.loadAndCreateWorker = function (workerUrl) {
        return __awaiter(this, undefined, undefined, function () {
            var workerCode, _a, workerBlob, blobUrl, error_1;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _b.trys.push([0, 4, , 5]);
                        if (!workerUrl) return [3 /*break*/, 2];
                        return [4 /*yield*/, this.loadWorkerScript(workerUrl)];
                    case 1:
                        _a = _b.sent();
                        return [3 /*break*/, 3];
                    case 2:
                        _a = "(".concat(getWorkerString.toString(), ")()");
                        _b.label = 3;
                    case 3:
                        workerCode = _a;
                        workerBlob = new Blob([workerCode], {
                            type: 'application/javascript',
                        });
                        blobUrl = URL.createObjectURL(workerBlob);
                        return [2 /*return*/, new Worker(blobUrl)];
                    case 4:
                        error_1 = _b.sent();
                        console.warn("CoralogixRum: Error creating worker ".concat(error_1));
                        return [2 /*return*/, undefined];
                    case 5: return [2 /*return*/];
                }
            });
        });
    };
    WorkerManager.prototype.loadWorkerScript = function (url) {
        return __awaiter(this, undefined, undefined, function () {
            var response;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 3, , 4]);
                        return [4 /*yield*/, fetch(this.getFullWorkerUrl(url))];
                    case 1:
                        response = _a.sent();
                        if (!response.ok) {
                            console.warn("CoralogixRum: Error fetching custom web worker");
                            return [2 /*return*/, ''];
                        }
                        return [4 /*yield*/, response.text()];
                    case 2: return [2 /*return*/, _a.sent()];
                    case 3:
                        _a.sent();
                        console.warn("CoralogixRum: Error fetching custom web worker");
                        return [2 /*return*/, ''];
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    WorkerManager.prototype.getFullWorkerUrl = function (workerUrl) {
        if (workerUrl.startsWith('http://') || workerUrl.startsWith('https://')) {
            return workerUrl;
        }
        return "".concat(CxGlobal.location.origin).concat(workerUrl);
    };
    return WorkerManager;
}());

var SessionRecorder = /** @class */ (function () {
    function SessionRecorder(sessionManager, recordConfig) {
        var _this = this;
        var _a;
        this.isAutoStartRecording = false;
        this.onlySessionWithErrorMode = false;
        this.recordEvents = [];
        this.recordEventsForSessionWithError = [[], []];
        this.segmentIndexCounter = {};
        this.hasRecording = false;
        this.hasScreenshot = false;
        this.recordingStopped = false;
        this.batchTimeDelay = BATCH_TIME_DELAY;
        this.isErrorOccurred = false;
        this.debugMode = !!((_a = getSdkConfig()) === null || _a === undefined ? undefined : _a.debug);
        this._recordingStopDueToTimeout = false;
        this.handleRecordEvent = function (event, isCheckout) {
            if (!_this.recordingStopped) {
                if (_this.onlySessionWithErrorMode) {
                    _this.handleRecordEventForSessionWithError(event, isCheckout);
                }
                else {
                    _this.recordEvents.push(event);
                }
            }
        };
        this.prepareRecordEventsBeforeSend = function () {
            if (_this.onlySessionWithErrorMode) {
                _this.prepareRecordEventsForSessionWithError();
            }
            else {
                if (!_this.recordEvents.length) {
                    return;
                }
                _this.compressRecordData(_this.recordEvents);
                _this.resetBatching();
            }
        };
        this.sendRecordEvents = function (workerData, shouldSplit) {
            var formData = new FormData();
            var metaData = _this.getMetadata(workerData, shouldSplit);
            formData.append('chunk', workerData.gzipBlob);
            formData.append('metaData', JSON.stringify(metaData));
            var sendRecordRequest = function () { return __awaiter(_this, undefined, undefined, function () {
                var response, _a;
                var _b;
                return __generator(this, function (_c) {
                    switch (_c.label) {
                        case 0:
                            _c.trys.push([0, 4, , 5]);
                            if (!!this.isErrorOccurred) return [3 /*break*/, 2];
                            return [4 /*yield*/, ((_b = this.request) === null || _b === undefined ? undefined : _b.send(formData))];
                        case 1:
                            _a = _c.sent();
                            return [3 /*break*/, 3];
                        case 2:
                            _a = undefined;
                            _c.label = 3;
                        case 3:
                            response = _a;
                            this.handleSessionRecordingResponse(response);
                            return [3 /*break*/, 5];
                        case 4:
                            _c.sent();
                            this.handleSessionRecordingResponse(undefined);
                            return [3 /*break*/, 5];
                        case 5: return [2 /*return*/];
                    }
                });
            }); };
            if (shouldSplit) {
                _this.batchTimeout = setTimeout(sendRecordRequest, _this.batchTimeDelay);
                _this.batchTimeDelay += BATCH_TIME_DELAY;
            }
            else {
                sendRecordRequest();
                _this.batchTimeDelay = BATCH_TIME_DELAY;
            }
        };
        CxGlobal[SESSION_RECORDER_KEY] = this;
        this.sessionManager = sessionManager;
        var onlySessionWithErrorMode = sessionManager.onlySessionWithErrorMode, maxRecordTimeForSessionWithError = sessionManager.maxRecordTimeForSessionWithError;
        var maxMutations = recordConfig.maxMutations, autoStartSessionRecording = recordConfig.autoStartSessionRecording, workerUrl = recordConfig.workerUrl;
        this.onlySessionWithErrorMode = onlySessionWithErrorMode;
        this.maxRecordTimeForSessionWithError = maxRecordTimeForSessionWithError;
        this.isAutoStartRecording = autoStartSessionRecording;
        this.maxMutations = maxMutations !== null && maxMutations !== undefined ? maxMutations : MAX_MUTATIONS_FOR_SESSION_RECORDING;
        this.recordConfig = this.prepareRecordConfig(recordConfig);
        if (CxGlobal.Worker) {
            this.workerManager = new WorkerManager();
            this.initializeSessionWorker(workerUrl);
        }
        else {
            if (this.debugMode) {
                console.warn(SESSION_RECORDING_DEFAULT_ERROR_MESSAGE);
            }
        }
    }
    SessionRecorder.prototype.getSessionHasScreenshot = function () {
        return this.hasScreenshot;
    };
    SessionRecorder.prototype.getSessionHasRecording = function () {
        var _a;
        return (this.hasRecording &&
            !!this.segmentIndexCounter[(_a = this.sessionManager.getActiveSession()) === null || _a === undefined ? undefined : _a.sessionId]);
    };
    SessionRecorder.prototype.updateSegmentIndexCounter = function (segmentIndexCounter) {
        this.segmentIndexCounter = segmentIndexCounter;
    };
    SessionRecorder.prototype.getIsAutoStartRecording = function () {
        return this.isAutoStartRecording;
    };
    Object.defineProperty(SessionRecorder.prototype, "recordingStopDueToTimeout", {
        get: function () {
            return this._recordingStopDueToTimeout;
        },
        set: function (value) {
            this._recordingStopDueToTimeout = value;
        },
        enumerable: false,
        configurable: true
    });
    SessionRecorder.prototype.startRecording = function () {
        return __awaiter(this, undefined, undefined, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.isWorkerReady];
                    case 1:
                        _a.sent();
                        if (!this.sessionWorker || this.recordRef) {
                            return [2 /*return*/];
                        }
                        if (this.debugMode) {
                            console.debug('Coralogix Browser SDK - Session recording started');
                        }
                        this.startMutationObserver();
                        this.resetBatching();
                        this.hasRecording = true;
                        this.recordingStopped = false;
                        this.isErrorOccurred = false;
                        this.recordingStopDueToTimeout = false;
                        this.recordRef = record(this.recordConfig);
                        this.startBatchingRecords();
                        return [2 /*return*/];
                }
            });
        });
    };
    SessionRecorder.prototype.screenshot = function (id) {
        this.hasScreenshot = true;
        var _a = this.sessionManager.getActiveSession() || {}, sessionId = _a.sessionId, sessionCreationDate = _a.sessionCreationDate;
        var snapshotRecords = snapshot(document, this.recordConfig);
        if (snapshotRecords) {
            this.sessionWorker.postMessage({
                event: 'sendRecordData',
                records: snapshotRecords,
                sessionId: sessionId,
                screenshotId: id,
                sessionCreationDate: sessionCreationDate,
            });
        }
    };
    SessionRecorder.prototype.stopRecording = function () {
        if (!this.recordRef) {
            return;
        }
        if (this.debugMode) {
            console.debug('Coralogix Browser SDK - Session recording stopped');
        }
        this.recordRef();
        this.recordRef = undefined;
        this.recordingStopped = true;
        this.hasRecording = false;
        this.prepareRecordEventsBeforeSend();
        this.clearIntervals();
        this.stopMutationObserver();
    };
    SessionRecorder.prototype.stopMutationObserver = function () {
        var _a;
        (_a = this.mutationObserver) === null || _a === undefined ? undefined : _a.disconnect();
    };
    SessionRecorder.prototype.startMutationObserver = function () {
        var _this = this;
        this.stopMutationObserver();
        this.mutationObserver = new MutationObserver(function (mutations) {
            if (mutations.length > _this.maxMutations) {
                var message = "Coralogix Browser SDK - Recording stopped due to too many mutations ".concat(mutations.length);
                console.warn(message);
                reportInternalEvent('recording-stop', message);
                _this.stopRecording();
            }
        });
        this.mutationObserver.observe(document, {
            attributes: false,
            attributeOldValue: false,
            characterData: false,
            characterDataOldValue: false,
            childList: true,
            subtree: true,
        });
    };
    SessionRecorder.prototype.clearIntervals = function () {
        if (this.batchingTimeInterval) {
            clearInterval(this.batchingTimeInterval);
        }
    };
    SessionRecorder.prototype.prepareRecordConfig = function (recordConfig) {
        var _a;
        var _b = recordConfig || {}, excludeDOMOptions = _b.excludeDOMOptions, recordConsoleEvents = _b.recordConsoleEvents;
        // @ts-ignore
        this.recordConfig = __assign(__assign({}, recordConfig), { emit: this.handleRecordEvent, checkoutEveryNms: this.onlySessionWithErrorMode
                ? this.maxRecordTimeForSessionWithError
                : undefined, slimDOMOptions: __assign(__assign({}, excludeDOMOptions), { script: (_a = excludeDOMOptions === null || excludeDOMOptions === undefined ? undefined : excludeDOMOptions.script) !== null && _a !== undefined ? _a : true }), plugins: recordConsoleEvents ? [getRecordConsolePlugin()] : [] });
        return this.recordConfig;
    };
    SessionRecorder.prototype.handleRecordEventForSessionWithError = function (event, isCheckout) {
        var shouldIgnoreEvent = this.sessionManager.sessionHasError &&
            !!isCheckout &&
            event.type === EventType.FullSnapshot;
        if (shouldIgnoreEvent) {
            return;
        }
        var shouldAddNewSnapshot = !!isCheckout && event.type === EventType.Meta;
        // Add new snapshot to the cache
        if (shouldAddNewSnapshot) {
            this.recordEventsForSessionWithError.push([]);
        }
        var _a = this.recordEventsForSessionWithError, length = _a.length, _b = length - 1, lastEvents = _a[_b];
        lastEvents.push(event);
    };
    SessionRecorder.prototype.prepareRecordEventsForSessionWithError = function () {
        var _a = this.recordEventsForSessionWithError, length = _a.length, _b = length - 2, beforeLast = _a[_b], _c = length - 1, last = _a[_c];
        if (this.sessionManager.sessionHasError) {
            var lastEvents = beforeLast.concat(last);
            if (!lastEvents.length) {
                return;
            }
            this.compressRecordData(lastEvents);
            this.resetBatching();
        }
        else {
            // If no error occurred, we need to keep only the last 2 snapshots
            this.recordEventsForSessionWithError = [beforeLast, last];
        }
    };
    SessionRecorder.prototype.compressRecordData = function (recordEvents) {
        var _a = this.sessionManager.getActiveSession() || {}, sessionId = _a.sessionId, sessionCreationDate = _a.sessionCreationDate;
        this.sessionWorker.postMessage({
            event: 'compressRecordData',
            records: recordEvents,
            sessionId: sessionId,
            sessionCreationDate: sessionCreationDate,
        });
    };
    SessionRecorder.prototype.registerToWorkerMessages = function () {
        var _this = this;
        this.sessionWorker.onmessage = function (_a) {
            var data = _a.data;
            switch (data.event) {
                case 'sendRecordData':
                    _this.sendRecordEvents(data, false);
                    break;
                case 'splitRecordData':
                    _this.sendRecordEvents(data, true);
                    break;
                case 'stopRecording':
                    _this.stopRecording();
                    break;
            }
        };
    };
    SessionRecorder.prototype.resetBatching = function () {
        if (this.onlySessionWithErrorMode) {
            this.recordEventsForSessionWithError = [[], []];
        }
        else {
            this.recordEvents = [];
        }
    };
    SessionRecorder.prototype.getMetadata = function (workerData, shouldSplit) {
        var sessionId = workerData.sessionId, sessionCreationDate = workerData.sessionCreationDate, screenshotId = workerData.screenshotId, gzipBlob = workerData.gzipBlob, chunkIndex = workerData.chunkIndex, totalChunks = workerData.totalChunks;
        var segmentIndex = 0;
        var application = getSdkConfig().application;
        var isScreenshot = !!screenshotId;
        if (!isScreenshot) {
            if (!this.segmentIndexCounter[sessionId]) {
                this.segmentIndexCounter[sessionId] = 0;
            }
            if (shouldSplit) {
                segmentIndex =
                    chunkIndex === totalChunks
                        ? this.segmentIndexCounter[sessionId]++
                        : this.segmentIndexCounter[sessionId];
            }
            else {
                segmentIndex = this.segmentIndexCounter[sessionId]++;
            }
            sessionStorage.setItem(SESSION_RECORDER_SEGMENTS_MAP, JSON.stringify(this.segmentIndexCounter));
        }
        var metaData = {
            segmentIndex: segmentIndex,
            segmentSize: gzipBlob.size,
            segmentTimestamp: getNowTime(),
            sessionCreationDate: sessionCreationDate,
            sessionId: sessionId,
            snapshotId: screenshotId,
            application: application,
            subIndex: chunkIndex !== null && chunkIndex !== undefined ? chunkIndex : -1,
        };
        return metaData;
    };
    SessionRecorder.prototype.handleSessionRecordingResponse = function (response) {
        if (!(response === null || response === undefined ? undefined : response.ok) && !this.isErrorOccurred) {
            console.warn(SESSION_RECORDING_NETWORK_ERR0R_MESSAGE);
            this.isErrorOccurred = true;
            this.stopRecording();
            if (this.batchTimeout) {
                clearTimeout(this.batchTimeout);
            }
        }
        else {
            this.isErrorOccurred = false;
        }
    };
    SessionRecorder.prototype.startBatchingRecords = function () {
        this.batchingTimeInterval = setInterval(this.prepareRecordEventsBeforeSend, MAX_BATCH_TIME_MS);
    };
    SessionRecorder.prototype.initializeSessionWorker = function (workerUrl) {
        var _this = this;
        this.isWorkerReady = new Promise(function (resolve, reject) {
            _this.workerManager
                .loadAndCreateWorker(workerUrl)
                .then(function (worker) {
                _this.sessionWorker = worker;
                if (_this.isAutoStartRecording) {
                    _this.startRecording();
                }
                _this.request = new Request({
                    suffix: SESSION_RECORDING_POSTFIX_URL,
                    headers: SESSION_RECORDING_DEFAULT_HEADERS,
                });
                _this.registerToWorkerMessages();
                resolve(true);
            })
                .catch(function (err) {
                if (_this.debugMode) {
                    console.warn('Coralogix Browser SDK - Web worker not created due to: ', err);
                }
                reject(err);
            });
        });
    };
    return SessionRecorder;
}());

export { SessionRecorder };