{"version":3,"file":"pageMayExitObservable.mjs","names":[],"sources":["../../src/browser/pageMayExitObservable.ts"],"sourcesContent":["import { Observable } from '../tools/observable'\nimport { objectValues } from '../tools/utils/polyfills'\nimport { isWorkerEnvironment } from '../tools/globalObject'\nimport { addEventListeners, addEventListener, DOM_EVENT } from './addEventListener'\n\nexport const PageExitReason = {\n  HIDDEN: 'visibility_hidden',\n  UNLOADING: 'before_unload',\n  PAGEHIDE: 'page_hide',\n  FROZEN: 'page_frozen',\n} as const\n\nexport type PageExitReason = (typeof PageExitReason)[keyof typeof PageExitReason]\n\nexport interface PageMayExitEvent {\n  reason: PageExitReason\n}\n\nexport function createPageMayExitObservable(): Observable<PageMayExitEvent> {\n  return new Observable<PageMayExitEvent>((observable) => {\n    if (isWorkerEnvironment) {\n      // Page exit is not observable in worker environments (no window/document events)\n      return\n    }\n    const { stop: stopListeners } = addEventListeners(\n      window,\n      [DOM_EVENT.VISIBILITY_CHANGE, DOM_EVENT.FREEZE],\n      (event) => {\n        if (event.type === DOM_EVENT.VISIBILITY_CHANGE && document.visibilityState === 'hidden') {\n          /**\n           * Only event that guarantee to fire on mobile devices when the page transitions to background state\n           * (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded.\n           */\n          observable.notify({ reason: PageExitReason.HIDDEN })\n        } else if (event.type === DOM_EVENT.FREEZE) {\n          /**\n           * After transitioning in background a tab can be freezed to preserve resources. (cf: https://developer.chrome.com/blog/page-lifecycle-api)\n           * Allow to collect events happening between hidden and frozen state.\n           */\n          observable.notify({ reason: PageExitReason.FROZEN })\n        }\n      },\n      { capture: true }\n    )\n\n    const stopBeforeUnloadListener = addEventListener(window, DOM_EVENT.BEFORE_UNLOAD, () => {\n      observable.notify({ reason: PageExitReason.UNLOADING })\n    }).stop\n\n    return () => {\n      stopListeners()\n      stopBeforeUnloadListener()\n    }\n  })\n}\n\nexport function isPageExitReason(reason: string): reason is PageExitReason {\n  return objectValues(PageExitReason).includes(reason as PageExitReason)\n}\n"],"mappings":";;;;;AAKA,MAAa,iBAAiB;CAC5B,QAAQ;CACR,WAAW;CACX,UAAU;CACV,QAAQ;AACV;AAQA,SAAgB,8BAA4D;CAC1E,OAAO,IAAI,YAA8B,eAAe;EACtD,IAAI,qBAEF;EAEF,MAAM,EAAE,MAAM,kBAAkB,kBAC9B,QACA,CAAA,oBAAA,QAA8C,IAC7C,UAAU;GACT,IAAI,MAAM,SAAA,sBAAwC,SAAS,oBAAoB;;;;;GAK7E,WAAW,OAAO,EAAE,QAAQ,eAAe,OAAO,CAAC;QAC9C,IAAI,MAAM,SAAA;;;;;GAKf,WAAW,OAAO,EAAE,QAAQ,eAAe,OAAO,CAAC;EAEvD,GACA,EAAE,SAAS,KAAK,CAClB;EAEA,MAAM,2BAA2B,iBAAiB,QAAA,sBAAuC;GACvF,WAAW,OAAO,EAAE,QAAQ,eAAe,UAAU,CAAC;EACxD,CAAC,CAAC,CAAC;EAEH,aAAa;GACX,cAAc;GACd,yBAAyB;EAC3B;CACF,CAAC;AACH;AAEA,SAAgB,iBAAiB,QAA0C;CACzE,OAAO,aAAa,cAAc,CAAC,CAAC,SAAS,MAAwB;AACvE"}