{"version":3,"file":"EmptyRootInstrumentation.cjs","names":["EmbraceInstrumentationBase"],"sources":["../../../../src/instrumentations/empty-root/EmptyRootInstrumentation/EmptyRootInstrumentation.ts"],"sourcesContent":["import { EmbraceInstrumentationBase } from '../../EmbraceInstrumentationBase/index.ts';\nimport type { EmptyRootInstrumentationArgs } from './types.ts';\n\n/*\n  EmptyRootInstrumentation observes changes to what is considered the root node of the application and emits a span\n  event on the session span if it ever finds it empty.\n */\nexport class EmptyRootInstrumentation extends EmbraceInstrumentationBase {\n  private readonly _observer: MutationObserver;\n  private readonly _emptyCheckDelayMs: number;\n  private readonly _rootNode: Node | null;\n\n  public constructor({\n    diag,\n    perf,\n    rootNode,\n    emptyCheckDelayMs = 500,\n  }: EmptyRootInstrumentationArgs) {\n    super({\n      instrumentationName: 'EmptyRootInstrumentation',\n      instrumentationVersion: '1.0.0',\n      diag,\n      perf,\n      config: {},\n    });\n\n    this._rootNode = rootNode;\n    this._emptyCheckDelayMs = emptyCheckDelayMs;\n\n    this._observer = new MutationObserver(\n      (mutationList: MutationRecord[], _observer: MutationObserver) => {\n        this._observerCallback(mutationList);\n      },\n    );\n\n    if (this._config.enabled && this._rootNode) {\n      this.enable();\n    } else if (!this._rootNode) {\n      this._diag.warn(\n        \"supplied root node was null, this instrumentation won't be enabled\",\n      );\n    }\n  }\n\n  public disable(): void {\n    this._observer.disconnect();\n  }\n\n  public enable(): void {\n    if (this._rootNode) {\n      this._observer.observe(this._rootNode, { childList: true });\n    }\n  }\n\n  protected _observerCallback(mutationList: MutationRecord[]): void {\n    let removedNodesFromRoot = false;\n    let addedNodesToRoot = false;\n\n    for (const mutation of mutationList) {\n      if (mutation.target === this._rootNode) {\n        if (mutation.removedNodes.length > 0) {\n          removedNodesFromRoot = true;\n        }\n\n        if (mutation.addedNodes.length > 0) {\n          addedNodesToRoot = true;\n        }\n      }\n    }\n\n    if (removedNodesFromRoot && !addedNodesToRoot) {\n      this._diag.debug(\n        'root node had child nodes removed without new ones being added, ' +\n          `checking if it's empty in ${this._emptyCheckDelayMs}ms`,\n      );\n\n      window.setTimeout(() => {\n        this._checkForEmptyRootNode();\n      }, this._emptyCheckDelayMs);\n    }\n  }\n\n  protected _checkForEmptyRootNode(): void {\n    if (this._rootNode?.childNodes.length === 0) {\n      this._diag.debug('root node was found to be empty');\n\n      const currentSessionSpan = this.sessionManager.getSessionSpan();\n      if (currentSessionSpan) {\n        currentSessionSpan.addEvent('empty-root-node', {\n          'emb.type': 'ux.empty_root_node',\n        });\n      } else {\n        this._diag.debug('no active session found to emit event on');\n      }\n    }\n  }\n}\n"],"mappings":";;;AAOA,IAAa,2BAAb,cAA8CA,+EAAAA,2BAA2B;CACvE;CACA;CACA;CAEA,YAAmB,EACjB,MACA,MACA,UACA,oBAAoB,OACW;AAC/B,QAAM;GACJ,qBAAqB;GACrB,wBAAwB;GACxB;GACA;GACA,QAAQ,EAAE;GACX,CAAC;AAEF,OAAK,YAAY;AACjB,OAAK,qBAAqB;AAE1B,OAAK,YAAY,IAAI,kBAClB,cAAgC,cAAgC;AAC/D,QAAK,kBAAkB,aAAa;IAEvC;AAED,MAAI,KAAK,QAAQ,WAAW,KAAK,UAC/B,MAAK,QAAQ;WACJ,CAAC,KAAK,UACf,MAAK,MAAM,KACT,qEACD;;CAIL,UAAuB;AACrB,OAAK,UAAU,YAAY;;CAG7B,SAAsB;AACpB,MAAI,KAAK,UACP,MAAK,UAAU,QAAQ,KAAK,WAAW,EAAE,WAAW,MAAM,CAAC;;CAI/D,kBAA4B,cAAsC;EAChE,IAAI,uBAAuB;EAC3B,IAAI,mBAAmB;AAEvB,OAAK,MAAM,YAAY,aACrB,KAAI,SAAS,WAAW,KAAK,WAAW;AACtC,OAAI,SAAS,aAAa,SAAS,EACjC,wBAAuB;AAGzB,OAAI,SAAS,WAAW,SAAS,EAC/B,oBAAmB;;AAKzB,MAAI,wBAAwB,CAAC,kBAAkB;AAC7C,QAAK,MAAM,MACT,6FAC+B,KAAK,mBAAmB,IACxD;AAED,UAAO,iBAAiB;AACtB,SAAK,wBAAwB;MAC5B,KAAK,mBAAmB;;;CAI/B,yBAAyC;AACvC,MAAI,KAAK,WAAW,WAAW,WAAW,GAAG;AAC3C,QAAK,MAAM,MAAM,kCAAkC;GAEnD,MAAM,qBAAqB,KAAK,eAAe,gBAAgB;AAC/D,OAAI,mBACF,oBAAmB,SAAS,mBAAmB,EAC7C,YAAY,sBACb,CAAC;OAEF,MAAK,MAAM,MAAM,2CAA2C"}